Jump to content
Registration disabled at the moment Read more... Ɨ

djhfwk

Members
  • Content Count

    15
  • Joined

  • Last visited

Community Reputation

0 Neutral

Technical Information

  • Delphi-Version
    Delphi 11 Alexandria

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. This is indeed great news — hats off to the hardworking author of ICS!
  2. In the current version (V9.4) of TSslWebSocketCli, the OnFrameRcvd event is triggered before the OnConnected event. This is the full set of modifications I made for OverbyteIcsWebSocketCli.pas, and it requires review. I added a new value to TWebSocketState: wssConnected. This state represents the situation where the server has already responded with "101 Switching Protocols", but the internal HttpState has not yet reached httpReady. In TSslWebSocketCli.IsWSConnected, HttpState need to be httpReady. I overrode StateChange to wait for this condition. I’m curious why the httpReady state is always slightly delayed. With this change, OnConnected is now triggered earlier, before OnFrameRcvd, which aligns better with the expected WebSocket event sequence. However, there is still one issue: OnFrameRcvd may be triggered before WSConnect returns. I'm not sure whether this behavior is acceptable or expected. Please advise. Using Demo: OverbyteIcsSnippets as client and OverbyteIcsSslMultiWebServ as server TWebSocketState = (wssHttp, wssConnecting, wssConnected, wssReady); function TSslWebSocketCli.WSConnect: Boolean; begin Result := False; RequestVer := '1.1'; HeaderUpgrade := ''; HeaderConnection := ''; HeaderSecWebSocketAccept := ''; HeaderSecWebSocketProtocol := ''; HeaderAccessControlAllowOrigin := ''; FWSFrameCounter := 0; if (DebugLevel >= DebugConn) then LogEvent('WebSocket: Connecting to: ' + URL); // WSState := wssConnecting; { in case server returns data quickly } Get; // sync request Result:= WSState = wssReady; end; procedure TSslWebSocketCli.StateChange(NewState: THttpState); begin inherited; if (NewState = httpReady) and (WSState = wssConnected) then begin WSState := wssReady; if Assigned(FOnWSConnected) then FOnWSConnected(Self); end; end; procedure TSslWebSocketCli.SocketDataAvailable(Sender: TObject; ErrCode: Word); var Len: Integer; { JK 28.11.2023 } BufPos : Integer; ParsedBytes : Integer; { JK 28.11.2023 end } ServerKey : String; s : AnsiString; KeyComp: Boolean; begin if (NOT (State = httpReady)) OR (WSState <> wssReady) then begin inherited SocketDataAvailable(Sender, ErrCode); // if FReceiveLen >= 2 then // LogEvent('WebSocket: Inherited Recv Raw: ' + IcsTBytesToString(FReceiveBuffer, FReceiveLen)); // !!! TEMP if (WSState <> wssConnecting) then Exit; //The protocol has been upgraded from HTTP to WebSocket. //This is when the connection is truly considered established. if (StatusCode = 101) then begin if SameText(HeaderUpgrade, 'websocket') and SameText(HeaderConnection, 'Upgrade') then begin s := AnsiString(ClientKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'); ServerKey := String(IcsBase64EncodeA(SHA1ofStr(s))); { V9.1 corrected string cast, V9.4 } KeyComp := (HeaderSecWebSocketAccept = ServerKey); if (NOT KeyComp) and (DebugLevel >= DebugConn) then LogEvent('WebSocket: Server Key Comparison Failed'); end else if (DebugLevel >= DebugConn) then LogEvent('WebSocket: Failed to Upgrade to WebSocket Protocol'); end else if (DebugLevel >= DebugConn) then LogEvent('WebSocket: Failed to Connect: ' + LastResponse); if KeyComp then begin if (DebugLevel >= DebugConn) then LogEvent('WebSocket: Connected OK'); //change the state to wssConnected, then wait httpReady WSState := wssConnected; { in case server returns data quickly } LastReceivedDataTickCount := IcsGetTickCount64; LastSentPingTickCount := 0; if (FWSPingSecs > 0) and (FWSPingSecs < 5) then FWSPingSecs := 5; FPeriodicTimer.Enabled := true; end else WSState := wssHttp; end; ........ OverbyteIcsWebSocketCli.pas
  3. At present, WSDumpFrame in OverbyteIcsWebSocketCli.pas truncates outgoing data frames at 132 bytes. Would it be possible to add a parameter to let developers control whether truncation occurs?
  4. // Fill data buffer with some data bytes and trailing spaces if Length (FDataBuf) < FSize then SetLength (FDataBuf, FSize); // buffer for data sent FRBufSize := Length (FReplyBuf); // space for several replies FillChar(FDataBuf[0], FSize, $20); S := AnsiString (FPingMsg); Move(S, FDataBuf[0], MinInteger(FSize, Length(S))); { V8.02 Msg now property, V8.04 ANSI } FillChar(FReplyBuf[0], FRBufSize, 0); Code should be fix with Move(S[1], FDataBuf[0], MinInteger(FSize, Length(S))); { V8.02 Msg now property, V8.04 ANSI }
  5. procedure THttpCli.DoRequestSync(Rq : THttpRequest); { V7.04 Timeout added } var TimeOutMsec : UINT; bFlag : Boolean; dwWaitMs : DWORD; AbortRequired : Boolean; { V8.71 JK } AbortMsg : String; { V8.71 JK } begin DoRequestAsync(Rq); if not Assigned(FCtrlSocket.Counter) then FCtrlSocket.CreateCounter; FCtrlSocket.Counter.LastSendTick := IcsGetTickCount64; // Reset counter { V8.71 } if FMultiThreaded then dwWaitMs:= 10 else dwWaitMs:= 1000; TimeOutMsec := FTimeOut * 1000; while FState <> httpReady do begin {$IFDEF MSWINDOWS} if MsgWaitForMultipleObjects(0, Pointer(nil)^, FALSE, dwWaitMs, QS_ALLINPUT) = WAIT_OBJECT_0 then {$ENDIF} MessagePump; { V8.71 JK see if user wants to abandon this request } In multithread mode, i think we can use lower period for MsgWaitForMultipleObjects.
  6. In some cases, I need synchronous functionality of dnsquery, so I made a change to OverbyteIcsDnsQuery.pas TDnsQuery now was inherited from TIcsWndControl. These functions were added. AAAALookup SendQuerySync MXLookupSync ALookupSync AAAALookupSync PTRLookupSync QueryAllSync QueryAnySync OverbyteIcsDnsQuery.pas
  7. 🤣 seems the problem is in FUdpSocket.RcvdCount , when it return 0, i changed it to 65535 manually, FUdpSocket.ReceiveFrom still can successfuly got data
  8. The UdpDataAvailable procedure should add len check before setlength, sometimes FUdpSocket.RcvdCount will return 0, and this will cause range error in delphi 11.1, although this can be turn off by uncheck the Range Check option in Project Options. procedure TSysLogServer.UdpDataAvailable(Sender: TObject; ErrCode: Word); var RawMessage : AnsiString; Len : Integer; Src : TSockAddrIn; SrcLen : Integer; SrcIP : AnsiString; SrcPort : AnsiString; begin SrcLen := SizeOf(Src); Len := FUdpSocket.RcvdCount; if Len = 0 then //this should be added, but will cause the UdpDataAvailable event hang randomly Exit; SetLength(RawMessage, Len); Len := FUdpSocket.ReceiveFrom(@RawMessage[1], Length(RawMessage), Src, SrcLen); if Len < 0 then Exit; SetLength(RawMessage, Len); SrcIP := IcsStrPas(inet_ntoa(Src.sin_addr)); SrcPort := AnsiString(IntToStr(ntohs(Src.sin_port))); if Assigned(FOnDataAvailable) then FOnDataAvailable(Self, SrcIP, SrcPort, RawMessage); end;
  9. In my prior snapshot, it's already the default order šŸ˜‚, the reset palette function works
  10. Radstudio 10.3 and later need NET 4.5, but XP do not support 4.5, so....
  11. Thanks, it's also in new order on OPTIONS, just curious why EMB changed it, reorder them manually is a disaster.....
  12. 😄 I reset the order of palette, then the order can't be back..... In 10.2 , the default order is Standard->Additional->Win32->System->..... but for 10.4, it's Standard->Xml->Live bindings->Live bindings Misc->.....
  13. djhfwk

    How to remove default DLL exports Delphi Rio

    not only dll but also exe have these exports. if you have source, modify the source and use BuildRTLGroup to rebuild the source, no source, use the tool to remove the exports.
  14. djhfwk

    Where is BrandingAPI

    VCLEditors include "BrandingAPI", but nowhere to found BrandingAPI. - -! Does anyone found it? thank you
Ɨ