I am using websockets to transfer video-y images from a server, written in Go, to a client which is an HTML page. My experience shared below is with Chrome.
I receive images via the onmessage handler of the websocket. On reception of an image, I might need to complete a number of tasks asynchronously before I can display the image. Even if these tasks are not finished, yet another onmessage() may fire. I do not want to queue images since at this point I'm not able to proceed as rapidly as the server is proceeding and because there is no point in displaying old images. I also do not want to drop these images, I don't wan't to receive them at all.
Would the client use a traditional TCP connection, it would just stop reading from the connection. This would cause the receive buffer to be filled, the receive window to be closed and, eventually, pause sending of images at the server. As soon the client starts reading, the receive buffers would empty, the receive window would open and the server resumes transmitting. Every time my server starts to send an image, it picks the freshest one. This pick-the-freshest behaviour, together with the flow control of TCP assures reasonable behaviour in many cases.
Is it possible to have the flow control features of TCP, on which websockets is based, with websockets? I'm especially interested in a solution that relies on TCP's flow control and no application level flow control since this tends to incur unwanted, additional latency.
I doubt what you are asking for is possible. There is no interface for that functionality in the WebSocket API spec. What the spec does outline, however, is a requirement that the underlying socket connection be managed in the background outside of the script that is using the WebSocket, so that the script is not blocked by WebSocket actions. When the socket receives inbound data, it wraps the data inside of a message and queues it for the WebSocket script to process. There is nothing to block the socket from reading more data while messages remain in the queue waiting for the script to process them.
The only real flow control you can implement in a WebSocket is an explicit one. When a message arrives, send back a message to acknowledge it. Make the server wait to receive that ack before sending its next message.