WSServer
Simple WebSocket server unit
- Active · last change 9-2-2026
- ★ 1 on GitHub
README
WSServer
Simple WebSocket server unit for Delphi / Object Pascal
How to use?
Add WSServer to your uses list:
uses WSServer;Declare WSServer:
var WSServer:TWSServer;In your code, init and destroy the WSServer:
procedure DoFantastic;
begin
WSServer := TWSServer.Create;
WSServer.SetPort(88);
WSServer.StartServer;
WSServer.OnClientFrameReceived := MyFrameReceived;
WSServer.OnClientConnect := MyConnect;
WSServer.OnClientDisconnect := MyDisconnect;
WSServer.OnClientSwitchProtocol := MySwitchProtocoll;
end;
Procedure LetTheFantasticOver;
begin
WSServer.StopServer;
WSServer.Free;
end;And define event handlers:
Procedure MyConnect(var Socket: TCustomWinSocket);
begin
// Connected
MySocket := Socket;
end;
Procedure MyDisconnect(var Socket: TCustomWinSocket);
begin
// Disconnected
end;
Procedure MySwitchProtocoll(var Socket: TCustomWinSocket; SecWebSocketAcceptKey, SecWebSocketKey,
SecWebSocketVersion, Path: string);
begin
// Switching protocol
// Sec-WebSocket-AcceptKey = SecWebSocketAcceptKey
// Sec-WebSocket-Key = SecWebSocketKey
// Sec-WebSocket-Version = SecWebSocketVersion
// Path = requested path, e.g. "/chat"
end;
Procedure MyFrameReceived(var Socket: TCustomWinSocket; Frame: string);
begin
// Frame contains a text message, decoded from UTF-8 to a normal Unicode string
end;
Procedure MyBinaryFrameReceived(var Socket: TCustomWinSocket; Data: TBytes);
begin
// Data contains a binary message as raw bytes
end;Sending frame over websocket:
procedure DoSendSomeText;
begin
WSServer.Send(MySocket, 'Text for send'); // text frame (string, UTF-8 on the wire)
// WSServer.Send(MySocket, MyBinaryData); // binary frame (TBytes)
end;Broadcasting to every connected client:
procedure DoBroadcastSomeText;
begin
WSServer.Broadcast('Text for everyone'); // text frame
// WSServer.Broadcast(MyBinaryData); // binary frame (TBytes)
end;Notes:
- The public API uses plain Unicode
stringfor text andTBytesfor binary data - noAnsiStringanywhere except internally, right at theTCustomWinSocket.SendText/ReceiveTextboundary (which isAnsiString-typed because that VCL component predates Unicode Delphi and only ever treats it as a raw byte buffer). - Text frames are UTF-8 on the wire, validated on receipt; invalid UTF-8, bad RSV bits, unknown opcodes, malformed fragmentation and invalid Close payloads are all rejected with an RFC 6455-compliant Close frame.
- Ping frames are answered with Pong automatically; Close frames are validated and acknowledged before the socket is closed.
- Fragmented messages (continuation frames) are reassembled before
OnClientFrameReceived/OnClientBinaryFrameReceivedfires. - Non-websocket / malformed HTTP requests get a
400 Bad Request, and an unsupportedSec-WebSocket-Versiongets a426 Upgrade Requiredinstead of being upgraded. WSServer.MaxFrameSize(default 16 MB) caps both a single frame's payload and a reassembled fragmented message;WSServer.MaxHTTPHeaderSize(default 8 KB) caps the handshake header block.Broadcastonly reaches clients that completed the WebSocket handshake, not ones still mid-HTTP.- Depends only on
System.SysUtils,System.Hash,System.NetEncodingandSystem.Win.ScktComp- all standard RTL/VCL units, no third-party packages.

