Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to terminate a WebSocket connection?

Tags:

Is it possible to terminate a websocket connection from server without closing the entire server? If it is then, how can I achieve it?

Note: I'm using NodeJS as back-end and 'ws' websocket module.

like image 560
m87 Avatar asked Dec 10 '16 09:12

m87


People also ask

How do I stop a WebSocket connection?

The WebSocket. close() method closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED , this method does nothing.

Do you need to close WebSocket?

If you are writing a server, you should make sure to send a close frame when the server closes a client connection. The normal TCP socket close method can sometimes be slow and cause applications to think the connection is still open even when it's not.

How do I stop a WebSocket connection in python?

Within the python terminal, the new status of the outputs are received by the python program. To stop the process, disconnect the websocket connection and stop the program by pressing Ctrl+C.

How do I know if my WebSocket is closed?

You can check if a WebSocket is disconnected by doing either of the following: Specifying a function to the WebSocket. onclose event handler property, or; Using addEventListener to listen to the close event.


1 Answers

So because of some sort of omission in the documentation regarding ws.close() and ws.terminate() I think the solutions in provided answers won't close the sockets gracefully in some cases, thus keeping them hanging in the Event Loop.

Compare the next two methods of ws package:

  • ws.close():

Initializes close handshake, sending close frame to the peer and awaiting to receive close frame from the peer, after that sending FIN packet in attempt to perform a clean socket close. When answer received, the socket is destroyed. However, there is a closeTimeout that will destroy socket only as a worst case scenario, and it potentially could keep socket for additional 30 seconds, preventing the graceful exit with your custom timeout:

// ws/lib/WebSocket.js:21
const closeTimeout = 30 * 1000; // Allow 30 seconds to terminate the connection cleanly.
  • ws.terminate():

Forcibly destroys the socket without closing frames or fin packets exchange, and does it instantly, without any timeout.

Hard shutdown

Considering all of the above, the "hard landing" scenario would be as follows:

wss.clients.forEach((socket) => {
  // Soft close
  socket.close();

  process.nextTick(() => {
    if ([socket.OPEN, socket.CLOSING].includes(socket.readyState)) {
      // Socket still hangs, hard close
      socket.terminate();
    }
  });
});

Soft shutdown

You can give your clients some time to respond, if you could allow yourself to wait for a while (but not 30 seconds):

// First sweep, soft close
wss.clients.forEach((socket) => {
  socket.close();
});

setTimeout(() => {
  // Second sweep, hard close
  // for everyone who's left
  wss.clients.forEach((socket) => {
    if ([socket.OPEN, socket.CLOSING].includes(socket.readyState)) {
      socket.terminate();
    }
  });
}, 10000);

Important: proper execution of close() method will emit 1000 close code for close event, while terminate() will signal abnormal close with 1006 (MDN WebSocket Close event).

like image 170
Damaged Organic Avatar answered Sep 26 '22 08:09

Damaged Organic