server.handleUpgrade() causes an attempt to reconnect the ws socket on refresh

See original GitHub issue

I am running a nodejs application which runs great the first time I use it but when I refresh and enter the new data Node crashes and gives me this. The error looks like this :

/www/wwwroot/domain.to/node_modules/ws/lib/websocket-server.js:267
      throw new Error(
      ^
Error: server.handleUpgrade() was called more than once with the same socket, possibly due to a misconfiguration
    at WebSocketServer.completeUpgrade (/www/wwwroot/domain.to/node_modules/ws/lib/websocket-server.js:267:13)
    at WebSocketServer.handleUpgrade (/www/wwwroot/domain.to/node_modules/ws/lib/websocket-server.js:245:10)
    at Server.upgrade (/www/wwwroot/tehran.us.to/node_modules/ws/lib/websocket-server.js:89:16)
    at Server.emit (events.js:327:22)
    at onParserExecuteCommon (_http_server.js:646:14)
    at onParserExecute (_http_server.js:587:3)

Here is my current config :

“ws”: “^7.3.1”, Node.js version(s): v14.4.0 OS version(s): Linux Ubuntu 18.04 LTS

I am not sure if this a bug with WS or nodejs but the socket is created twice upon refreshing. Is there a way to avoid this recreation? How can I assure every user from each browser can access the application and reuse it?

This is the rest of the code for partial reproduction :

const app = express();
const options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
const server = https.createServer(options, app)

server.listen(3000, function () {
  console.log("Express server listening on port " + 3000);
});
I also use Websocket on the same end point and the code looks like this :

const wss = new Websocket.Server({ server })
    console.log(url)
    wss.on('connection', ws => {
        console.log('user is connected to the server #mainpage')

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
lpincacommented, Aug 25, 2020

If I use noServer I cannot use SSL anymore, is that correct?

No, it is totally unrelated. You can use an external HTTPS server.

const server = https.createServer(options);
const wss = new Websocket.Server({ noServer: true });

wss.on('connection', function (ws, request) {
  // ...
});

server.on('upgrade', function (request, socket, head) {
  wss.handleUpgrade(request, socket, head, function (ws) {
    wss.emit('connection', ws, request);
  });
});

I think this is happening because my code runs once without error, the second time I do not close ws so it tries to reopen the port which it cannot and then the error occurs. I tried to close the socket with ws.close() at a timer but I don’t think this is the correct way of doing this.

It doesn’t matter, the browser closes the connection when you refresh the page.

0reactions
lpincacommented, Aug 26, 2020
export default async (url, server) => {
    const wss = new Websocket.Server({ server })
    console.log(url)
    
    wss.on('connection', ws => {
        console.log('user is connected to the server #mainpage')
        ws.send(JSON.stringify({
            percentage: 100,
            status: done,
            fileName: nameofmyfile
        }))
    })
    wss.on('close', ws => {
        ws.send('connection close')
    })
}

This creates a new WebSocket server every time the function is called and it seems you are calling it from the handler of app.get('/x'). This is wrong, you should create a single WebSocket server and use the existing WebSocket connection, if there is one, when the user visits /x.

Take a look at this example https://github.com/websockets/ws/blob/master/examples/express-session-parse/index.js to get an idea.

When the user visit /x you get the WebSocket connection from the map of WebSocket connections and use it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to deal with server.handleUpgrade() was called more ...
I am running a nodejs application which runs great the first time I use it but when I refresh and enter the ...
Read more >
Handling Websockets with Express
Handling websockets with an Express server in Node.js is easy with the ws module. Here's how it works.
Read more >
Real-Time in Angular: A journey into Websocket and RxJS
I'll be using Angular 8 for the client, Node.js for the server which uses the ws library as it is simple to use,...
Read more >
Client Initialization
The randomization factor used when reconnecting (so that the clients do not reconnect at the exact same time after a server crash, for...
Read more >
WebSocket
Requests to WebSocket use wss://ws.site.com , a subdomain that leads to the WebSocket server, while https://site.com goes to the main HTTP- ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found