[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)