Streaming Data over WebSockets with ws-wrapper

TLDR: WebSockets are cool, and my little library makes using them a bit easier. I would love feedback to improve the library!

Raw WebSockets give you one primitive: send(). ws-wrapper builds a practical communication layer on top of that, so instead of parsing and routing raw messages yourself, you get:

  • Named events – emit an event on one end, handle it on the other (similar to Socket.IO)

  • Request / response – send a request and get back a Promise that resolves (or rejects) with the remote handler’s return value

  • Channels – logically namespace events over a single WebSocket connection

  • Streaming – anonymous (request-scoped) channels permit streaming / iterator patterns

  • Cancellation – cancel in-flight requests using the standard AbortSignal API, with cooperative cancellation support on the remote end

  • Bi-directionality – clients can request data from the server, and the server can also request data from clients

1 Like

Neat, so this is kind of like a full message bus over ws - I like it!

What was the inspiration for this? NATS?

Yeah, it’s basically structured message passing and remote procedure calls over WebSockets.

I developed this library a long time ago for the Sweet Amanda’s vending kiosk as an alternative to socket.io – I wanted something lighter. It has evolved a lot since then, and I just added new functionality like request-scoped channels (I call them anonymous channels since they are unnamed). If I were to build a web app, I think I would use this instead of a RESTful HTTP API.

WebSockets are awesome, and it’s nice to have a fairly lightweight abstraction on top of that to do useful web programming.

NATS is also great but I find it even harder to fully comprehend than socket.io… but of course, NATS solves other problems with JetStream and all of that jazz. It also works over TCP whereas this is intended exclusively for WebSockets.

I have many future aspirations that might one day be realized with the help of AI. We shall see!

I have also been working on a WebUI app using this Go lib: GitHub - webui-dev/go-webui: Use any web browser as GUI, with Go in the backend and modern web technologies in the frontend. · GitHub

With WebUI, you can do rudimentary data transfer over the WebUI WebSocket connection, but it was just easier to create a separate WebSocket connection (wrapped with ws-wrapper) to pass data around and call functions on the Go backend. The app talks to devices over Modbus, so one idea I had was to have a “connect” request that returns an anonymous channel (which is also an iterable) in JavaScript. Then, you read from the iterable using a for await loop, and it starts polling various Modbus registers from the Go backend and sending the register values to the JS frontend. When you’re done, you simply close the anonymous channel, and everything gets cleaned up. It works pretty well so far.