In the ws Node.js WebSocket library, regarding the event socket.on('close', ...), is there any direct way (i. e. by inspecting the event) to determine if the client has closed the socket OR the server closed it for this client?
Even when the server explicitly sets a specific close code (4001), the handler on the server side for the close event gets a generic close code (1005).
So there is no way around but to remember it somewhere if the server closed the socket?
If the client closed it, it knows it closed it. But if it doesn't then it must be server. The same thing can happen server-side
Related
I have a Spring integration server running on a tcp-inbound-gateway and a client that connects to the server using regular java sockets.
The client connects to the server, the server processes the request and then sends the response. The client reads in the response, then closes the connection using socket.close().
On the server side I have a tcp-connection-event-inbound-channel-adapter configured and I see this:
TcpConnectionExceptionEvent [source=org.springframework.integration.ip.tcp.connection.TcpNetConnection#2294e71d, cause=org.springframework.integration.ip.tcp.serializer.SoftEndOfStreamException: Stream closed between payloads], [factory=crLfServer, connectionId=127.0.0.1:52292:5556:add2ff2a-b4ff-410d-8e60-d6b1a388044e]
Is this normal behavior?
Yes; it's normal - we emit application events whenever an exception occurs on a socket, the SoftEndOfStreamException occurs when the socket is closed "normally" (i.e. between messages).
We could, I suppose, suppress that particular event, but some find it useful.
I'm using uwsgi's websockets support and so far it's looking great, the server detects when the client disconnects and the client as well when the server goes down. But i'm concerned this will not work in every case/browser.
In other frameworks, namely sockjs, the connection is monitored by sending regular messages that work as heartbeats/pings. But uwsgi sends PING/PONG frames (ie. not regular messages/control frames) according to the websockets spec and so from the client side i have no way to know when the last ping was received from the server. So my question is this:
If the connection is dropped or blocked by some proxy will browsers reliably (ie. Chrome, IE, Firefox, Opera) detect no PING was received from the server and signal the connection as down or should i implement some additional ping/pong system so that the connection is detected as closed from the client side?
Thanks
You are totally right. There is no way from client side to track or send ping/pongs. So if the connection drops, the server is able of detecting this condition through the ping/pong, but the client is let hung... until it tries to send something and the underlying TCP mechanism detect that the other side is not ACKnowledging its packets.
Therefore, if the client application expects to be "listening" most of the time, it may be convenient to implement a keep alive system that works "both ways" as Stephen Clearly explains in the link you posted. But, this keep alive system would be part of your application layer, rather than part of the transport layer as ping/pongs.
For example you can have a message "{token:'whatever'}" that the server and client just echoes with a 5 seconds delay. The client should have a timer with a 10 seconds timeout that stops every time that messages is received and starts every time the message is echoed, if the timer triggers, the connection can be consider dropped.
Although browsers that implement the same RFC as uWSGI should detect reliably when the server closes the connection cleanly they won't detect when the connection is interrupted midway (half open connections)t. So from what i understand we should employ an extra mechanism like application level pings.
If I use my app(ios with c++ websocket code) with websocket connect nitrous.io, it will close connection if there is no signal.
Somebody has answered that this is nitrous.io feature,
but if I use web browser/html websocket connect to nitrous.io, it never closes the connection.
Confused by the different behavior.
(***web browser/html websocket connect to nitrous.io also closes after no signal for few hours)
Your comment welcome
I use soŃket.io (transport flashsockets), the client flash application with websockets library (binary sockets). How can I detect client disconnection immediately, such as if the Internet connection is broken? Currently, the disconnect event is triggered after a delay that is set to heartbeattimeout. What happens if you turn off heartbeats? If the connection is closed from flash, then all is well.
The frontend is nginx with tcp-proxy-module. Does this require specific settings timeouts?
io.set("close timeout", 1);
Refer to:https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
I have a webapp, which is running in a browser. That webapp is connected to a server, which uses websockets. So the communication between the server and my client/browser is based on websockets. If some magic event occurs on the server, some webservice sends a new XML / JSON to my webapp and the new data gets displayed.
But how do i, as the client / browser, know if the connection is stil alive? Lets say i do not get any new XML for about 30 seconds. How would i know if the connection is closed/broken/server offline or everything is fine, but on the server himself no new magic event occured.
A websocket connection object has a readyState field which will tell you if the connection is still active (from the dart documentation). The readyState can be either
0 - connection not yet established
1 - conncetion established
2 - in closing handshake
3 - connection closed or could not open
You can also define an event handler for the websocket close event if this is something you'd like to handle (try to reconnect, etc).
3 ways:
rely on TCP to detect loss of connectivity, which will ultimately pop up in JS onclose event
send WebSocket pings from server .. browsers will reply with WS pongs, loss of connectivity is probably more robustly detected also on client side
send app level heartbeats from browser to server, server need to have logic to reply. you can't trigger WS pings from browsers (in JS)