I have a Websocket connection being served from http-kit (Clojure, and it works great). I send pings from the client to make sure we're still connected, and everything works fine there. My question is, do people bother pinging client from server in these cases?
I was trying to set something up to remove the channel from the server if I didn't get a response, but it's not very functional-friendly to set up timed processes and alter state to track the ping-pong cycle, so it was getting a little ugly. Then I thought, the server can handle hundreds of thousands of simultaneous connections, should I just not worry about a few broken threads? How do people typically handle (or not handle) this?
The WebSocket protocol itself has heart beating to keep the connection alive. If you wanted an additional layer on top of that you could use the STOMP protocol, which coordinates heartbeats between client/server.
The one STOMP implementation I know of for the JVM is Stampy. There’s one for JS too, stompjs. Note: the heartbeat implementation differs between these libs, I believe the Stampy one is incorrect. You’d have to roll your own.
Related
As I understand it, Websockets use a Ping to detect that they are still connected. Except of course Chrome which leaves it to apps to do the ping themselves.
I'd like to understand if its possible for a connection to become unstable between pings such that a frame of data is not received... but to stabilize again by the time the next ping is sent. In other words: is it possible to have an apparently good websocket connection, but for data to fail to arrive?
Question relates to Is it possible to miss websocket events which remains unanswered and side-tracked into long-polling and socket-io.
Thanks!
This is heavily dependent on the client software (browser) that you use.
The websockets depend on a TCP connection which will make sure the message arrives to destination. Except if the network connection is down, of course.
However, some clients (browsers) will suspend the inactive tabs and will not process the events. If your page is inactive, it "may" fail to send data to the server because it will not be executed at all. On the other hand, it "may" also fail to receive data because the handler will not be executed at all.
Meanwhile, even if inactive, the machine will still receive the ping packets. So it is really about whether or not your client software gives it back to your code or not.
I am learning to use SignalR and so far I had success in doing so. I can implement Hubs, I can implement business logic, I can invoke client-side functions from server for whom I want, I can invoke server-side methods from client-side, this stuff is great. The thing puzzling me is the theory.
In fact, I gathered info from this video. SignalR is using WebSockets, which provide a full duplex channel over a single TCP connection. If no WebSockets are available, then the fallback protocol will be EventSource. If that is unavailable, then a Forever Frame will be used. If that is unavailable, then Long Polling will be used. It is rather strange for me that a very hacky solution, like a forever frame is preferred over the older convention and I am interested about the rationale behind SignalR's decision to have forever frames as the third option and polling as fourth option.
I have tried to find out the answer to this question and I found out that it is rumored that there is a 3x max latency time in the case of long polling compared to forever frames. Is this a fact and if so, is it a fact for all browsers, or for a subset?
foreverFrame works a bit like serverSentEvents - there is one long running http request which the server never terminates but uses to push data to the client. longPolling works differently - there is a poll http request which is being closed by the server each time there is data for the client to read (or a timeout expires). If the client wants to read more data it needs to open a new http request which again will be closed by the server as soon as there is any data for the client. In other words, in case of foreverFrame the server is pushing data to the client using an already established channel while in case of longPolling the client is continuously creating http requests to get the data from the server.
I have a client/server setup in which clients send a single request message to the server and gets a bunch of data messages back.
The server is implemented using a ROUTER socket and the clients using a DEALER. The communication is asynchronous.
The clients are typically iPads/iPhones and they connect over wifi so the connection is not 100% reliable.
The issue I’m concern about is if the client connects to the server and sends a request for data but before the response messages are delivered back the communication goes down (e.g. out of wifi coverage).
In this case the messages will be queued up on the server side waiting for the client to reconnect. That is fine for a short time but eventually I would like to drop the messages and the connection to release resources.
By checking activity/timeouts it would be possible in the server and the client applications to identify that the connection is gone. The client can shutdown the socket and in this way free resources but how can it be done in the server?
Per the ZMQ FAQ:
How can I flush all messages that are in the ZeroMQ socket queue?
There is no explicit command for flushing a specific message or all messages from the message queue. You may set ZMQ_LINGER to 0 and close the socket to discard any unsent messages.
Per this mailing list discussion from 2013:
There is no option to drop old messages [from an outgoing message queue].
Your best bet is to implement heartbeating and, when one client stops responding without explicitly disconnecting, restart your ROUTER socket. Messy, I know, this is really something that should have a companion option to HWM. Pieter Hintjens is clearly on board (he created ZMQ) - but that was from 2011, so it looks like nothing ever came of it.
This is a bit late but setting tcp keepalive to a reasonable value will cause dead sockets to close after the timeouts have expired.
Heartbeating is necessary for either side to determine the other side is still responding.
The only thing I'm not sure about is how to go about heartbeating many thousands of clients without spending all available cpu just on dealing with the heartbeats.
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.
I have spring + SockJS application, that is using ActiveMQ as message broker.
Can I have two sockets on same JSP page, one with sending and receiving ,and the other one only for receiving stomp messages(with lot of traffic).Is it guaranteed taht all messages will be delivered and received from both of sockets?
Regards,
Marko
While connected, yes. If you lose the connection at any point, you will lose everything between disconnecting and reconnecting. A related discussion of this issue comes to this conclusion.
Keep in mind that SockJS may result in different connections types on different clients, such as websocket, xhr, xdr, etc. On any connection SockJS will still use TCP and will still guarantee in-order delivery. However, non-websocket connections can take longer to trigger the close event, so you'll have longer black-out periods at the client. Almost any service needs to worry about this, because SockJS will sometimes fail to connect a websocket and "downgrade" to xhr (in my experience under high instantaneous load).
A good pattern is to add a reconnect in the close event handler. The close even is fired even when a connection fails to be established, which means you'll want a back-off latency on the reconnect to prevent a self-inflicted DDoS on your server. Separately, I add sequential packet numbers, and treat any client that detects a missing packet as a late joiner. (See this related ZMQ discussion on late joiners.) Your application needs may vary.