WsAdapter creates two sockets on same server and causes nest to die on ws connection
See original GitHub issueBug Report
Current behavior
Creating a new nest instance with ws websocket adapter, nest creates two sockets on the same server. Using nest’s default server booted in main.ts is common getting a websocket connection through this server by upgrading the connection. As I understood the docs, this should be accomplished by just not specifying a port number with the @WebSocketGateway()
decorator.
Expected behavior
Allow me to open my socket without crashing nest 😃
Possible Solution
The ws-Adapter runs new websocket.Server(...)
twice on the same httpServer in line 37 below: https://github.com/nestjs/nest/blob/2bdcdb5814db144082b0e4107f7b02f9d2d7a720/packages/platform-ws/adapters/ws-adapter.ts#L30-L51
The create
-method is called twice in packages/websockets/socket-server-provider.ts
createSocketServer
callAdapter.create
https://github.com/nestjs/nest/blob/2bdcdb5814db144082b0e4107f7b02f9d2d7a720/packages/websockets/socket-server-provider.ts#L34- and then calls
createWithNamespace
->getServerOfNamespace
-> callsAdapter.create
again https://github.com/nestjs/nest/blob/2bdcdb5814db144082b0e4107f7b02f9d2d7a720/packages/websockets/socket-server-provider.ts#L66-L70
The adpter.create()
-method is aware that no server should actually be created but the app’s server should be used. In new ws.Server()
the socket-server registers for the upgrade-event on the underlaying httpServer. Since two Socket’s are created on this server, both registered upgrade-handlers are fired from the same server-instance and ws
throws
Error: server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration
at WebSocketServer.completeUpgrade (node_modules\ws\lib\websocket-server.js:267:13)
at WebSocketServer.handleUpgrade (node_modules\ws\lib\websocket-server.js:245:10)
at Server.upgrade (node_modules\ws\lib\websocket-server.js:89:16)
at Server.emit (events.js:201:15)
at onParserExecuteCommon (_http_server.js:580:14)
at onParserExecute (_http_server.js:520:3)
Edit: The upgrade-handlers are called when a WebSocket trys to connect, not on application startup - and then nest crashes.
Although the error comes from ws
it is due to wrong usage by nest.
Environment
Nest version: 7.4.1
Issue Analytics
- State:
- Created 3 years ago
- Comments:10 (4 by maintainers)
There were numerous hints from Damien Arrachequesne in the issue tracker that plain ws is the way to go. Today, it may look different again.
In the next major release (v8), this will simply crash during the application bootstrap process, warning you that “namespaces” are no supported by the “ws” package (it’s an exclusive socket.io feature).