Search code examples
websocketf#suave

Websockets in Suave


I've been looking into using websockets with the Suave web server. Unfortunately, it's not very well documented, and all I've managed to find was this: https://github.com/SuaveIO/suave/tree/master/examples/WebSocket

However, that only shows the websocket responding to the client that made the request, and I want to basically have the socket respond to all connected clients. Something like a chat server.

I've used SignalR in the past, but would prefer to avoid it for this.

So, how would I go about having the Suave server send data to all connected websocket clients?


Solution

  • Suave doesn't provide anything like that out of the box, however you can easily extend the example to do so.

    The socket handler ws passed to the handShake function can pass the client information outside, and you can build a send/broadcast API around it.

    The ws function can be modified for example like this

    let ws onConnect onDisconnect (webSocket: WebSocket) (context: HttpContext) =
        let loop () = (* the socket logic stays the same *)
    
        socket {
            onConnect webSocket context
            try
                do! loop ()
            finally
                onDisconnect context
        }
    

    Then it's up to you to inject the onConnect and onDisconnect handles to register/unregister clients.

    I use a MailboxProcessor to serialize the Connect/Disconnect/Send operations, alternatively it's easy to use Reactive Extensions, or a shared mutable concurrent storage like ConcurrentDictionary...