Skip to content

TTMSFNCWebSocketServer

The TTMSFNCWebSocketServer is a non-visual component enabling communication to websocket clients. It implements the RFC 6455 standard for websocket communication protocol.

Start/stop the server

Starting/stopping the server is as simple as setting the Active property.

procedure TForm1.startBtnClick(Sender: TObject);
begin
  TMSFNCWebSocketServer1.Active := True;
end;

procedure TForm1.stopBtnClick(Sender: TObject);
begin
  TMSFNCWebSocketServer1.Active := False;
end;

Allowing connections

By default all connections are allowed as long as they initiate a valid handshake request. After the handshake request is validated, the OnAllow event is triggered. This event has an AAllow: Boolean parameter which can be used to allow or disallow a connection regardless of the handshake request. The AConnection parameter gives access to the HandshakeRequest property which lets the details of the request be inspected.

procedure TForm2.TMSFNCWebSocketServer1Allow(Sender: TObject;
  AConnection: TTMSFNCWebSocketServerConnection; var aAllow: Boolean);
begin
  //Allow all connections
  AAllow := True
end;

Send data

Use BroadcastMessage(AMessage: string) or BroadcastData(AData: TBytes) to broadcast a string or binary messages to all connected clients.

procedure TForm1.broadcastBtnClick(Sender: TObject);
begin
  TMSFNCWebSocketServer1.BroadcastMessage('Hello client!');
end;

Use SendMessageTo(AMessage, ASelector) or SendDataTo(AData, ASelector) to send string or binary messages to connected clients. The ASelector callback determines which clients should the message be sent to.

//Forward incoming message to all client, except the one the message came from
procedure TForm2.TMSFNCWebSocketServer1MessageReceived(Sender: TObject;
  AConnection: TTMSFNCWebSocketConnection; const aMessage: string);
begin
  TMSFNCWebSocketServer1.SendMessageTo(AMessage, function(AClientConnection: TTMSFNCWebSocketServerConnection): Boolean
    begin
      Result := AClientConnection <> AConnection;
    end);
end;

Send in multiple frames

By default all messages are sent in one single frame. If SplitMessage is set to True, the message will be split up into multiple frames based on size defined by FrameSize. Size of the frame includes frame headers too.

Receive data/messages

When a string message arrives from one of the clients the OnMessageReceived event will be triggered. The AMessage parameter will contain the string message from the client.

When a binary message arrives from one of the clients the OnBinaryDataReceived event will be triggered. The AData parameter will contain the binary message from the client.

Ping and pong

Whenever a ping message arrives from a client the OnPing event is triggered and an automatic pong message is sent back.

If the Options property contains the twsoManualPong value the poing message is NOT sent automatically. In this case the OnPing can be used to send manually or skip it entirely.

procedure TForm2.TMSFNCWebSocketServer1Ping(Sender: TObject;
  AConnection: TTMSFNCWebSocketConnection; const aData: TArray<System.Byte>);
begin
  AConnection.SendSimpleFrame(focPong);
end;

The OnPong event is triggered whenever a pong message is received from a client.

Custom connection data

The TTMSFNCWebSocketServerConnection.UserData object property allows you to store any kind of custom data paired to your connection. It also has an OwnsUserData property which will free the object automatically if it's set to True. If it's set to False, the object needs to be released manually.

When to create/assign the UserData object is depending on the use-case. When the data that needs storing is arriving from the client itself as a form of message, then the OnMessageReceived event is the place to handle this. For example as a form of JSON message:

type
  TMyDataObject = class(TObject)
  private
    FID: string;
  public
    property ID: string read FID write FID;
  end;

procedure TForm1.TMSFNCWebSocketServer1MessageReceived(Sender: TObject;
  AConnection: TTMSFNCWebSocketConnection; const aMessage: string);
var
  json: TJSONValue;
  jObj: TJSONObject;
  t, id, s, lID: string;
  i: Integer;
begin
  json := TJSONObject.ParseJSONValue(AMessage);
  try
    if json.TryGetValue<string>('type', t) then
    begin
      if (t = 'user-data') and not Assigned(TTMSFNCWebSocketServerConnection(AConnection).UserData) then
      begin
        json.TryGetValue<string>('id', id);
        TTMSFNCWebSocketServerConnection(AConnection).OwnsUserData := True;
        TTMSFNCWebSocketServerConnection(AConnection).UserData := TMyDataObject.Create;
        TMyDataObject(TTMSFNCWebSocketServerConnection(AConnection).UserData).ID := id;
        //...
      end
      else if t = 'join' then 
      begin
        //...
      end
      //elseā€¦.
  finally
    json.Free;
  end;
end;

When the server is the one that automatically assigns some data, it needs to be inspected where that should happen.

For example: The server wants to assign a unique ID for each new connection. In this case we can use the OnHandshakeResponseSent event where the server responds to the websocket handshake so the connection is estabilished.

procedure TForm1.TMSFNCWebSocketServer1HandshakeResponseSent(Sender: TObject;
  AConnection: TTMSFNCWebSocketServerConnection);
begin
  AConnection.OwnsUserData := True;
  AConnection.UserData := TMyDataObject.Create;
  TMyDataObject(AConnection.UserData).ID := GetMyUniqueID;
end;

Secure connection

Traffic over a websocket server can be protected via TLS. In order to enable this, set the UseSSL property to True.

The CertificateFile, CertificateKeyFile and RootCertificateFile properties can be used to define the path to the certificate file(s).

For secure connection OpenSSL libraries are required.

Properties

Property name Description
Active: Boolean Start or stop the server.
CertificateFile: string Path to the certificate file. Used when UseSSL is set to True.
CertificateKeyFile: string Path to the certificate key file. Used when UseSSL is set to True.
FrameSize: UIn64 The size of each frame to be sent. Used when SplitMessage is set to True.
Options: TTMSFNCWebsocketOptions A set connection related options. Values are:
- twsoFrameByFrame: Do not assemble the frames
- twsoSkipUpgradeCheck: Do not check handshake Upgrade header
- twsoSkipVersionCheck: Do not check handshake version
- twsoManualPong: Do not send pong automatucally
- twsoManualClose: Do not send close reply automatically
PathName: string Name of the path.
For example: ws://localhost:8888/path
Port: Integer Port number. Default setting is 8888.
RootCertificateFile: string Path to the root certificate file. Used when UseSSL is set to True.
SplitMessage: Boolean If set to True, messages are split into multiple frames based on FrameSize.
UseSSL: Boolean If set to True, the server communication is protected via TLS.

Methods

Method name Description
BroadcastMessage(AMessage: string) Broadcasts a string message to all connected clients.
BroadcastData(AData: TBytes) Broadcasts a binary message to all connected clients.
SendMessageTo(AMessage: string; ASelector: TTMSFNCWebSocketSendToCallback) Sends a string message to connected clients. The ASelector callback determines to which clients the message should be sent.
SendDataTo(AData: TBytes; ASelector: TTMSFNCWebSocketSendToCallback) Sends a binary message to connected clients. The ASelector callback determines to which clients the message should be sent.

Events

Event name Description
OnAllow Event triggered to allow or disallow a client connection.
OnBinaryDataReceived Event triggered when a binary message arrives to the server.
OnClose Event triggered when a close frame is sent by the client.
OnConnect Event triggered when a clients connects to the server. This is not equal to when the client is connected (handshake successfully finished).
OnDisconnect Event triggered when a client disconnects.
OnHandshakeResponseSent Event triggered when the handshake response is sent to the client.
OnMessageReceived Event triggered when a string message arrives to the server.
OnPing Event triggered when a ping message arrives from a client.
OnPong Event triggered when a pong message arrives from a client.