WebsocketServerTransport bind does not resolve when given a WebsocketServer which leverages an listening http.Server instance
viglucci opened this issue · comments
As described below, when calling bind
on a WebsocketServerTransport
created with a WebsocketServer
that uses a listening http.Server
, the bind
call never resolves.
------- Original comment body:
Hi @viglucci, I'm finally getting around to integrating RSocket 1.0 in a greenfield project, so I'll be adding to this thread as and when I find anything worth sharing.
So far loving the simple integration with RxJS, particularly on the client side this has reduced our RSocket setup code by at least 10x. Great work on that.
I had one small hiccup that I've had to hack around on the server side. We're running an Express server with some "normal" HTTP endpoints, and we want RSocket to only listen on a /subscriptions
URL. The way we're doing this is:
We have an existing httpServer: http.Server
, and my initial instinct was to instantiate the transport like this:
const websocketServer = new WebSocket.Server({
server: httpServer,
path: '/subscriptions',
})
const transport = new WebsocketServerTransport({
wsCreator: () => websocketServer,
})
const rsocketServer = new RSocketServer({
transport,
// ...
})
We were calling this as follows in our server setup code:
await listen() // () => new Promise<void>((resolve) => httpServer.listen(env.port, resolve))
await rsocketServer.bind()
This didn't work though, as rsocketServer.bind()
never resolves.
I noticed that WebsocketServerTransport#connectServer
uses the listening
event to resolve the server:
Manually adding websocketServer.addListener('listening', () => console.log('I am listening'))
, and also adding 'connection'
listeners showed me that the WebSocket server was listening correctly.
Instantiating the WebSocket.Server
inside the wsCreator
callback did not help either. WebSocket.Server
just binds to the HTTP server's listening
event (code), so this never emits if the server is already listening.
I can fix this for now by instantiating the RSocket server before listening on the HTTP server, eg.:
const rsocketStarted = rsocketServer.bind()
await listen()
await rsocketStarted
...but it's a bit confusing that the order makes a difference.
I can see why we'd want to await the listening
event inside connectServer
, but is there potentially some way of checking whether the WebSocket.Server
is already listening and immediately resolving if so?
Anyway not a blocker at all, just a papercut :)
Will report on more as I come across it & once again thanks a lot for working on this!
Originally posted by @lachenmayer in #158 (comment)