Suave websocket server with a continuous feed
Why am I doing this?
I recently wrote a blog post using Suave websockets. It was a dead-simple example of a websocket server that just echoes back what the client sends to it. I made a new example that is just a tiny bit more useful. I made the Suave websocket server return a continuous feed of the current date and time. Exciting stuff.
See my previous article, Plugging in Elm and Suave with websockets on .NET Core 2.0
You can find the source code for my new and improved websocket log server on my Github repo here.
What did I change?
Let's walk through a bit of the code
In let app: WebPart
I changed the route to make them more obvious when I use them in a client.
let app : WebPart =
choose [
path "/websocket/datelog" >=> handShake wsDateLog
// path "/websocketWithSubprotocol" >=> handShakeWithSubprotocol (chooseSubprotocol "test") ws
path "/websocketWithError/datelog" >=> handShake (wsWithErrorHandling wsDateLog)
GET >=> choose [ path "/" >=> file "index.html"; browseHome ]
NOT_FOUND "Found no handlers." ]
I changed the name of the ws
function to distinguish it so I can have multiple routes that do different things with a websocket. I changed the name to wsDateLog
.
I changed the function ws
, now wsDateLog
, to a function with a forevar! loop that sends back the current date, and does this every 2 seconds.
I changed wsWithErrorHandling
to take a function that returns the data so I could I plug in any function here that I want in the future.
let wsWithErrorHandling ws (webSocket : WebSocket) (context: HttpContext) =
In the path
s I changed them to pass in the wsDateLog
instead of ws
.
path "/websocket/datelog" >=> handShake wsDateLog
// path "/websocketWithSubprotocol" >=> handShakeWithSubprotocol (chooseSubprotocol "test") ws
path "/websocketWithError/datelog" >=> handShake (wsWithErrorHandling wsDateLog)
Now we are ready to roll with a fancy date sender.
This will work with the Elm client from the previous article, just replace the echoServer
with one of the paths in the Suave app
.
I also have an example of where I did this in Elm, but instead of rolling all of the dates returned, I just displayed the last 10. Find that code here.
Thoughts
My thoughts on this are that I now have the building blocks for a websocket server that will send any kind of continuous feed to a client. This could a log feed or a status of something. I am sure there are many applications. All I have to do is replace the date calculation with, say, a call to a database and stuff like that.
I don't know how I feel about the sleep bits. Probably there is a better thing to do here.
As always, if you have any questions or comments please tweet me @marneedear or leave a comment.