[HN Gopher] Show HN: Socket-call - Call socket.io events like no...
___________________________________________________________________
Show HN: Socket-call - Call socket.io events like normal JavaScript
functions
Hello HN, I built a Typescript library (named socket-call, for
lack of a more sexy name) whose goal is to be able to call
socket.io events as regular functions. So you declare your server-
side like so: ... const listenEvents =
(services: UserServices) => ({ // Add your events here, the
name of the event is the name of the function login: async
(username: string) => { services._socket.data.user = {
username }; console.log(`User ${username} logged in`);
setInterval(() => { // Calling an event that's handled
client-side services.showServerMessage(`You're still
logged in ${username}!`) }, 1000); return `You
are now logged in ${username}!`; }, }); and
then on the client side you call them like normal async Javascript
functions (and you can also create client-side event handlers):
... const user = socket.addNamespace<UserEmitEvents,
UserListenEvents>( '/user' ); // Calling
an event that's declared server-side
user.login(username.value).then((message) => {
console.log('Server acked with', message); });
// Handling an event that is sent by the server
user.showServerMessage = (message) => { console.log('Server
sent us the message', message); } I use this
library for my own projects and would be interested to receive
feedback about it :-)
Author : bperel
Score : 37 points
Date : 2025-06-16 11:40 UTC (11 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| klabb3 wrote:
| This appears to me like the NATS "request-response" pattern. They
| also have first-class support for this in their client libs.
| Under the hood, they create and subscribe to an ephemeral topic
| where servers can send the response to. (Perhaps even streamed
| multiple responses but you'd need to double check that.) They
| also have websocket support btw, so it can be used by web
| browsers.
| chrisweekly wrote:
| I like the ergonomics, this looks like it could be useful. Thanks
| for sharing!
| benpacker wrote:
| You can do with with trpc WebSocket transport
| dataviz1000 wrote:
| trpc has the benefit of being highly adopted, supported, and
| with a community.
| xixixao wrote:
| Convex[0] also gives you type-safe persistence (in addition to
| type-safe web-socket communication).
|
| [0] https://docs.convex.dev/quickstart/script-tag
| ossobuco wrote:
| I don't know, socket.io already feels like an unnecessary
| abstraction to me, and this is another abstraction on top of it.
| I generally dislike APIs that hide what's happening under "magic"
| abstractions, plus this seems leaky, as it abstracts on socket.io
| but requires you to know how it works.
| imtringued wrote:
| socket.io is probably one of the most unnecessary libraries on
| this planet. Websockets are already as simple as possible.
|
| In fact, websockets work so well I use them as a generic TCP
| replacement, because the message oriented transport model gives
| me 99% of what I need with the exception of custom message
| types. Leaving that out was a massive letdown to me, because
| you now need to carry a way to identify the message type inside
| the body, rather than just throwing the message itself into the
| appropriate protocol parser (e.g. a schema based binary
| format).
| JonnyReads wrote:
| I have to admit I've never tried to use web sockets without
| socket.io. Are they really as simple as you claim?
| efilife wrote:
| Same here. I guess we'll just have to try
|
| It doesn't look difficult at all now I look at it
| https://javascript.info/websocket
| korkybuchek wrote:
| > socket.io is probably one of the most unnecessary libraries
| on this planet. Websockets are already as simple as possible.
|
| Eh... While I agree that socket.io is one of those libraries
| you could probably "write" in an afternoon, and Websockets
| _are_ simple, there are a couple of things that are kinda
| painful to rewrite time after time: -
| keepalives to detect dead sockets - reconnection logic
| with backoff - ability to switch to long-polling for
| weird environments - basic multiplexing/namespacing
| andoando wrote:
| And automatic json parsing of messages
| Karrot_Kream wrote:
| Websockets already have keepalives. Everything but long
| polling is doable in a few hours and can probably be one-
| shotted by an LLM. For long-polling, you can just drop down
| to Fetch calls.
| sourcemap wrote:
| This is true. Just a few days ago I had Claude one-shot
| some WebSocket utilities for reconnect and message
| queueing. It took 2 minutes.
|
| I've written countless WebSocket wrappers in the past
| (similar aversion to socket.io as others in this thread).
| The one-shot output was perfect. Certainly better than my
| patience would've allowed.
|
| Maybe socket.io is doing something fancy on the server
| side, but for clients, it's absolutely overkill.
| paulbjensen wrote:
| Although WebSockets are simple to use, there are a bunch of
| issues that the spec doesn't cater for when using them:
|
| 1. Connectivity. The WebSocket connection is only as
| persistent as the underlying network connection between the
| client and the server. A person playing a web-based game on a
| mobile device on a train that then goes under a tunnel is a
| good example.
|
| WebSockets do not reconnect if they close unexpectedly. In
| such cases, you have to throw the WebSocket instance away and
| create a new one, and so you end up having to implement your
| own reconnectivity logic.
|
| 2. Message Sending. Messages will only be sent if the
| connection is open. If it is closed, not only do the messages
| not get sent, but they don't get queued up either, so they
| end up disappearing into the ether.
|
| If you want to guarantee message sending, then you end up
| having to implement a queuing mechanism that is linked to
| knowing the status of the WebSocket connection, and is able
| to send when the conditions are right.
|
| 3. If you don't use WSS (WebSocket Secure Server) for the
| WebSocket host and connection url, then the WebSocket
| connections can get interfered with if they are connecting
| over a mobile network - ISPs sometimes inject packets which
| ends up distorting WebSocket connections over http. But I
| think since the days of Ed Snowden's leaks everyone has their
| production WebSocket systems setup using WSS.
|
| This comes from the experience many years ago of working on a
| WebSocket-powered web framework called SocketStream which ran
| into these issues, and then some years ago I managed to build
| a library that focussed on dealing with those WebSocket-
| related issues, called Sarus:
| https://github.com/anephenix/sarus
|
| WebSockets is great though, and there is still much that can
| be done with it as this library in the HN post demonstrates.
| pcthrowaway wrote:
| socket.io has a lot of optimizations that can help scale
| message broadcast to many connected users, and also handles
| things like client disconnections, delivery confirmation,
| etc.
|
| It is not unnecessary, and you probably could build something
| that does the same things in a day or two, but I'd be
| surprised if it was something that scales as well to >100,000
| simultaneously connected people
| dataviz1000 wrote:
| That is awesome! I see you use Proxy which is a very cool way to
| achieve this. [0] I saw this approach using Proxy when hacking
| VSCode's ipc where they use it define services from ipc channels/
| [1]
|
| I did something similar using VSCode's core ipc / rpc which only
| requires a transport (protocol) to implement {send, onMessage}. I
| use it in a Chrome extension so I have to implement my own
| socket.io and port message passing protocols. Some of the
| benefits are being able to send a message from MAIN world of an
| injected content script (if you want to intercept all fetch and
| XMLHttpRequest requests, for example) through a tunnel in the
| isolated world content script to the side panel which could
| theoretically tunnel it to a server over socket.io. If I have a
| Math service, for example, that only adds two numbers, it can be
| called from anywhere in the system with `await
| mathService.add(1,1);` with mathServer being dependency injected
| using constructor(@IMathService private readonly mathService:
| IMathService). This is how VSCode manages calling code across
| hundreds of different isolated JavaScript runtime environments.
|
| What I did was a bit overkill and likely trpc would have been
| good enough if I knew about it when I started.
|
| [0] https://github.com/bperel/socket-
| call/blob/e0076d7887397a92a...
|
| [1]
| https://github.com/microsoft/vscode/blob/24c0ff16c250f2b39ee...
___________________________________________________________________
(page generated 2025-06-16 23:01 UTC)