Skip to main content
Version: 20

WebSocketServer

The WebSocketServer class allows you to create and configure a WebSocket server in 4D. Once the 4D WebSocket server is active, you can open and use WebSocket connections between 4D and clients using the WebSocketConnection class.

History
ReleaseChanges
20Added
About WebSocket Servers

The WebSocket protocol provides full-duplex communication channel between a WebSocket Server and a client (e.g. a Web browser). For more information on WebSocket servers, read this page on Wikipedia.

See also

See also this blog post about the 4D WebSocket server.

Requirements

To create and handle your WebSocket Server in 4D, you will have to use two 4D build-in classes:

  • this class (4D.WebSocketServer) to manage the server itself,
  • the 4D.WebSocketConnection class to manage connections and messages.

In addition, you will have to create two user classes that will contain callback functions:

  • a user class to handle server connections,
  • a user class to handle messages.

You must create the WebSocket server within a worker to keep the connection alive.

The 4D Web Server must be started.

Example

In this basic example, our WebSocket server will return messages in uppercase.

  1. Create the WebSocket server using a worker (mandatory) and pass your server connection class as parameter:
	//create an instance of the user class
//that will handle the connections to the server
var $handler:cs.myServerHandler
$handler:=cs.myServerHandler.new()

CALL WORKER("WebSocketServer"; Formula(wss:=4D.WebSocketServer.new($handler)))
//assign a variable (wss) to the WebSocket allows you
//to call wss.terminate() afterwards
  1. Define the myServerHandler user class containing callback function(s) used to handle connections to the server:
//myServerHandler class

Function onConnection($wss : Object; $event : Object) : Object
//returns an instance of the user class
//that will handle the messages
return cs.myConnectionHandler.new()
  1. Define the myConnectionHandler user class containing callback function(s) used to handle messages:
// myConnectionHandler class

Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
//resends the message in uppercase
$ws.send(Uppercase($message.data))

Client-Side JS

See this blog post for an example of client-side Javascript code handling a WebSocket connection.

WebSocketServer object

WebSocket server objects provide the following properties and functions:

.connections : Collection
all current connections handled by the WebSocket server
.dataType : Text
the type of the data received or sent
.handler : Object
the accessor that gets the WSSHandler object used to initiate the WebSocket server
.path : Text
the pattern of the path to access the WebSocket server
.terminate()
.terminate( timeout : Integer )

closes the WebSocket server
.terminated : Boolean
True if the WebSocket server is closed

4D.WebSocketServer.new()

4D.WebSocketServer.new( WSSHandler : Object { ; options : Object } ) : 4D.WebSocketServer

ParameterTypeDescription
WSSHandlerObject->Object of the user class declaring the WebSocket Server callbacks
optionsObject->WebSocket configuration parameters
Result4D.WebSocketServer<-New WebSocketServer object

The 4D.WebSocketServer.new() function creates and starts a WebSocket server that will use the specified WSSHandler callbacks and (optionally) options, and returns a 4D.WebSocketServer object.

Calling this function requires that the 4D Web Server is started. The host and port of the WebSocket server are the same as the host and port of the 4D Web Server.

WSSHandler parameter

In the WSSHandler parameter, pass an instance of a user class that will be called every time an event occurs on the WebSocket server --essentially, connection events. The class should define the following callback functions (only onConnection is mandatory):

PropertyTypeDescriptionDefault
onConnectionFunction(mandatory) Callback when a new client connection is started (see below)undefined
onOpenFunctionCallback when the WebSocket server is started (see below)undefined
onTerminateFunctionCallback when the WebSocket server is terminated (see below)undefined
onErrorFunctionCallback when an error has occurred (see below)undefined

WSHandler.onConnection(WSServer : Object ; event : Object) : Object | null

ParameterTypeDescription
WSServer4D.WebSocketServer<-Current WebSocket server object
eventObject<-Parameters
typeText"connection"
requestObjectrequest object. Contains information on the connection request (see below)
Function resultObject->connectionHandler object (see below). If this function returns a connectionHandler object, a 4D.WebSocketConnection object is automatically created and added to the collection of connections. This object is then received as parameter in each function of the connectionHandler object. If the returned value is null or undefined, the connection is cancelled.

This callback is called when the handshake is complete. It must be called with a valid connectionHandler object to create the WebSocket connection, otherwise the connection is cancelled.

WSHandler.onOpen(WSServer : Object ; event : Object)

ParameterTypeDescription
WSServer4D.WebSocketServer<-Current WebSocket server object
eventObject<-Parameters
typeText"open"

Event emitted when the websocket server is started.

WSHandler.onTerminate(WSServer : Object ; event : Object)

ParameterTypeDescription
WSServer4D.WebSocketServer<-Current WebSocket server object
eventObject<-Parameters
typeText"terminate"

Event emitted when the HTTP server or the WebSocket server is closed.

WSHandler.onError(WSServer : Object ; event : Object)

ParameterTypeDescription
WSServer4D.WebSocketServer<-Current WebSocket server object
eventObject<-Parameters
typeText"error"
errorsCollectionCollection of 4D error stack in case of execution error
  • [].errCode (number) - 4D error code
  • [].message (text) - Description of the 4D error
  • [].componentSignature (text) - Signature of the internal component which returned the error
  • Event emitted when an error occurs on the WebSocket server.

    Example of WSSHandler class

    This example of a basic chat feature illustrates how to handle WebSocket server connections in a WSSHandler class.

    //myWSServerHandler class

    Function onConnection($wss : Object; $event : Object) : Object

    If (VerifyAddress($event.request.remoteAddress))
    // The VerifyAddress method validates the client address
    // The returned WSConnectionHandler object will be used
    // by 4D to instantiate the 4D.WebSocketConnection object
    // related to this connection
    return cs.myConnectionHandler.new()
    // See connectionHandler object
    Else
    // The connection is cancelled
    return Null
    End if

    Function onOpen($wss : Object; $event : Object)
    LogFile("*** Server started")

    Function onTerminate($wss : Object; $event : Object)
    LogFile("*** Server closed")

    Function onError($wss : Object; $event : Object)
    LogFile("!!! Server error: "+$event.errors.first().message)

    request object

    A request object contains the following properties:

    ParameterTypeDescription
    headersObjectThe client HTTP GET request. headers.key=value (value can be a collection if the same key appears multiple times)
    queryObjectObject that contains the URL parameters. For example, if parameters are: ?key1=value1&key2=value2 -> query.key1=value1, query.key2=value2
    urlTextcontains only the URL that is present in the actual HTTP request. Ex: GET /status?name=ryan HTTP/1.1 -> url="/status?name=ryan"
    remoteAddressTextIP Address of the client

    connectionHandler object

    As a result of the WSHandler.onConnection callback, pass a connectionHandler object, which is an instance of a user class that will be called every time an event occurs in the WebSocket connection --essentially, messages received. The class should define the following callback functions (only onMessage is mandatory):

    ParameterTypeDescription
    onMessageFunction(mandatory) Function called when a new message is received from this connection
    onOpenFunctionFunction called when the 4D.WebSocketConnection is created
    onTerminateFunctionFunction called when this connection is terminated
    onErrorFunctionFunction called when an error occured

    connectionHandler.onMessage(ws : 4D.WebSocketConnection ; event : Object)

    ParameterTypeDescription
    ws4D.WebSocketConnection<-Current WebSocket connection object
    eventObject<-Parameters
    typeText"message"
    dataText / Blob / Objectdata sent by the client

    This Callback for WebSocket data. Called each time the WebSocket receives data.

    connectionHandler.onOpen(ws : 4D.WebSocketConnection ; event : Object)

    ParameterTypeDescription
    ws4D.WebSocketConnection<-Current WebSocket connection object
    eventObject<-Parameters
    typeText"open"

    Called when the connectionHandler object is created (after WSS.onConnection event).

    connectionHandler.onTerminate(ws : 4D.WebSocketConnection ; event : Object)

    ParameterTypeDescription
    ws4D.WebSocketConnection<-Current WebSocket connection object
    eventObject<-Parameters
    typeText"terminate"
    codeNumberStatus code indicating why the connection has been closed. If the WebSocket does not return an error code, code is set to 1005 if no error occurred or to 1006 if there was an error.
    reasonTextString explaining why the connection has been closed. If the websocket doesn't return an reason, code is undefined

    Function called when the WebSocket is closed.

    connectionHandler.onError(ws : 4D.WebSocketConnection ; event : Object)

    ParameterTypeDescription
    ws4D.WebSocketConnection<-Current WebSocket connection object
    eventObject<-Parameters
    typeText"error"
    errorsCollectionCollection of 4D errors stack in case of execution error
  • [].errCode (number) - 4D error code
  • [].message (text) - Description of the 4D error
  • [].componentSignature (text) - Signature of the internal component which returned the error
  • Function called when an error has occurred.

    Example of connectionHandler class

    This example of a basic chat feature illustrates how to handle messages in a connectionHandler class.

    // myConnectionHandler Class

    Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
    // Resend the message to all chat clients
    This.broadcast($ws;$message.data)

    Function onOpen($ws : 4D.WebSocketConnection; $message : Object)
    // Send a message to new connected users
    $ws.send("Welcome on the chat!")
    // Send "New client connected" message to all other chat clients
    This.broadcast($ws;"New client connected")

    Function onTerminate($ws : 4D.WebSocketConnection; $message : Object)
    // Send "Client disconnected" message to all other chat clients
    This.broadcast($ws;"Client disconnected")

    Function broadcast($ws : 4D.WebSocketConnection; $message:text)
    var $client:4D.WebSocketConnection
    // Resend the message to all chat clients
    For each ($client; $ws.wss.connections)
    // Check that the id is not the current connection
    If ($client.id#$ws.id)
    $client.send($message)
    End if
    End for each

    options parameter

    In the optional options parameter, pass an object that contains the following properties:

    PropertyTypeDescriptionDefault
    pathTextRepresents the path to access the WebSocket server. If no path is defined, the WebSocket server manages all the connectionsundefined
    dataTypeTextType of the data received through the connectionHandler.onMessage and the data send by WebSocketConnection.send() function. Values: "text", "blob","object"). If "object": (send) transforms object into a json format and sends it; (reception): receives json format and transforms it into objecttext

    .connections

    .connections : Collection

    Description

    The .connections property contains all current connections handled by the WebSocket server. Each element of the collection is a WebSocketConnection object.

    When a connection is terminated, its status changes to "Closed" and it is removed from this collection.

    .dataType

    .dataType : Text

    Description

    The .dataType property contains the type of the data received or sent.

    This property is read-only.

    .handler

    .handler : Object

    Description

    The .handler property contains the accessor that gets the WSSHandler object used to initiate the WebSocket server.

    .path

    .path : Text

    Description

    The .path property contains the pattern of the path to access the WebSocket server. If no path was defined, the WebSocket server manages all connections.

    This property is read-only.

    .terminate()

    .terminate()
    .terminate( timeout : Integer )

    ParameterTypeDescription
    timeoutInteger->Waiting time in seconds before terminating the WebSocket server

    Description

    The .terminate() function closes the WebSocket server.

    By default, if no timeout value is set, the function initializes close handshake and waits to receive close frame from the peer, after that sending FIN packet in attempt to perform a clean socket close. When answer received, the socket is destroyed.

    If a timeout value is set:

    • when the waiting time is reached, forcibly destroys the socket.
    • if timeout = 0, forcibly destroys the socket without closing frames or fin packets exchange, and does it instantly without waiting time.

    .terminated

    .terminated : Boolean

    Description

    The .terminated property contains True if the WebSocket server is closed.

    This property is read-only.