Home > Software engineering >  When is it preferable to use ws.terminate() VS ws.close()
When is it preferable to use ws.terminate() VS ws.close()

Time:10-16

I know terminate hard closes a socket not letting it hang or send more packets like close does, and terminate sends a different code when closing a socket (1006 vs close sending 1000). So this raises the question, why would I even used ws.close() when I dont plan on reopening a socket? Ive seen so many examples that just use ws.close() and never reopen it. Is it just not well known or standard or is there something behind the scenes Im not aware of?

CodePudding user response:

  • Closing the web socket will wait for buffered messages to be finished, and initiate the closing handshake. This includes an optional close code and an optional close reason. It tells client that the websocket is now closed and no further messages will be sent, and once the other end acknowledges that, the tcp connection will be closed. See 1.4 Closing handshake:

    The closing handshake is intended to complement the TCP closing handshake (FIN/ACK), on the basis that the TCP closing handshake is not always reliable end-to-end, especially in the presence of intercepting proxies and other intermediaries.

    By sending a Close frame and waiting for a Close frame in response, certain cases are avoided where data may be unnecessarily lost. For instance, on some platforms, if a socket is closed with data in the receive queue, a RST packet is sent, which will then cause recv() to fail for the party that received the RST, even if there was data waiting to be read.

    This is considered a clean closure. The close code informs the status on the other end, or leads to status 1005 if omitted.

  • Terminating the web socket will just drop the connection. It calls socket.destroy(), no close frames are sent or anything, not even the tcp connection is closed cleanly with FIN. This leads to status 1006 on the other end, after it has run into a timeout.

The downside of having a closing handshake in the protocol is that a closing connection might be left hanging in a limbo state when the other end is no longer responding at all. Only a timeout will end that, with various problems.

Why would I even use ws.close() when I don't plan on reopening a socket?

You should always gracefully close() your web socket to notify the other end that the connection ends. You should also send the close reason 1000 (as the client) or 1001 (as the server) to tell the other end that they should not try to reconnect.

If a server needs to drop the connection but will become available again soon after, it might forcibly close the TCP connection. This will cause the client to immediately detect an abnormal closure, and it might attempt to automatically reconnect after a short time. (There is no method to do this in the ws library, you'd have to call ws._socket.end()).

If you terminate() a working connection, the other end will not notice anything. Only when it tries to send something (e.g. a ping()), after some timeout it will find that the tcp connection was lost and the websocket will become abnormally closed. Don't do that!

You should only ever call terminate() if you have determined that the connection has already been lost - like in the heartbeat example. This will free up resources on your end quickly and immediately fire the respective stream events on the ws object.

  • Related