So far I only used HTTP/1.1, but recently I switched to HTTP/2. On 1.1 I ran into request number limit issues, but HTTP/2 uses one connection with multiplexing, does that mean that I can keep multiple SSE channels open with no problems, or should I still use only one with some internal message routing solution?
If you want to be safe: Use just one channel or only a few of them and multiplex internally.
Longer answer: The reason that more channels caused problems with HTTP/1.1 is that each channel required a dedicated TCP connection, and browsers limited the number of concurrent TCP connections for each tab (I think to something around 10). With HTTP/2 making concurrent HTTP requests is possible on a single connection. therefore opening multiple concurrent SSE streams is more likely be possible. However browsers (and also webservers) may still limit the number of concurrent HTTP/2 streams they support over a TCP connection. HTTP/2 even supports that by allowing each peer in a HTTP/2 setting to communicate the maximum amount of concurrent streams it supports (SETTINGS_MAX_CONCURRENT_STREAMS). To be safe you would need to figure out what the limit is that your target browsers and your web server supports and use a lower number of SSE streams. I unfortunately don't know whether it's part of any HTML or browser specification, that they all should support at least a well-specified number of concurrent requests over HTTP/2. If you keep the number of requests low you avoid to run into problems.
One other advantage for using only a few channels is that you can still support HTTP/1.1 clients well. And not only those which might be directly connected to your server but also those which might connect through a proxy-server (which means the connection browser<->proxy uses HTTP/1.1 and proxy<->webserver uses HTTP/2).
Related
Does sending large files over a websocket "block" websocket for other messages while the large files are being sent?
Does sending the files via independent Http requests while the other messages continue to be sent over WS have any distinct advantage "in keeping the WS unblocked"?
Assume 1 network card.
In case of WebSocket over HTTP/1.1, yes, the upload of a large file (in the form of a large WebSocket message) blocks the WebSocket connection.
In case of WebSocket over HTTP/2 (if supported by both the client and server), one HTTP/2 stream will upload the large file, and another HTTP/2 stream is be used to carry WebSocket messages. In this case, the problem becomes the HTTP/2 flow control window, which may be exhausted by the large upload stream, leaving the WebSocket message stream stalled (so that messages are queued and delayed). Unfortunately, the details of this queueing/delay depend on the client and on the server implementations, so you have to try.
Typically implementations do a good job at interleaving streams, so rarely the possible stalls are a problem.
For WebSocket over HTTP/1.1, if you open multiple WebSocket connections, you may be able to send files and messages in parallel, using N WebSocket connections for the files, and 1 WebSocket connection for the messages, for example.
Some non-browser clients allow you to open multiple HTTP/2 connections to the same domain, so again you will have the chance to send files and messages in parallel. However, to my knowledge, browsers do not allow more than 1 HTTP/2 connection to the same domain, so the parallelism is there, but constrained by the HTTP/2 flow control window.
Not sure what you mean by "keeping the WS unblocked", but HTTP/1.1 works in the same way as WebSocket for what pertains its usage of connections.
If you are in a browser environment, browsers allow 6-8 HTTP connections to the same domain, and typically unlimited (or at least many more) WebSocket connections.
So if you want to send, say, 10 large files, 6-8 of them will be uploaded via HTTP, but the remaining will be queued waiting for one of the HTTP connections to finish the previous upload.
Meanwhile, you can use the WebSocket connection to send messages.
In case of HTTP/2, browsers only open 1 connection, so you may use HTTP/2 streams for the uploads and a WebSocket over HTTP/2 stream for the messages, but they will all share the same HTTP/2 flow control window, potentially stalling each other.
All in all, WebSocket has not been designed for large uploads.
I would not be surprised if you hit WebSocket message size limits, as servers cannot allow clients to upload messages of arbitrary size (as it will blow up the server memory). The same is true for clients; browsers have typically small limits for the size of WebSocket messages that they receive, independently of whether HTTP/1.1 or HTTP/2 is used.
If you really need to upload large files, I think a solution where you upload via HTTP (which allow larger sizes, for example when using multipart/form-data), and keep small messaging via WebSocket is optimal.
The use of HTTP/2 may hit the HTTP/2 flow control window limit, but you have a limit in 6-8 connections in HTTP/1.1 too, so again you have to try and see if you hit any limit, and if you do, which limit it is in what case.
Using HTTP for uploads makes less likely that you hit WebSocket message size limits that are not known in advance and possibly different from client to client (browser to browser), and you don't want to implement your own splitting and merging of large uploads via WebSocket to respect those limits.
I'm taking a google video course about the http protocol. The http 1.1 introduced so called the pipeling technique to reduce a time between requestes and responses. There might occur the head of line blocking, so browsers uses parallel connections to avoid the HOL blocking.
I wonder, how does browsers send parallel network packets? I have never thought about possibility of multiple packets sent simultaneously, is it even possible to send parallel requests through a "cable"? How does it work?
Another thing is the http 2.0, does browsers implement parallel connections in this protocol? The http 2.0 uses the streams, but I'm not sure how browsers handles it.
Nothing in HTTP is truly parallel. If multiple resources are to be tranferred at once, clients have to establish multiple connections. For HTTP/1.1, it is not uncommon to see three to five of these per host.
HTTP/2 is a bit different in that it can engage into interleaving: The smalest entity in HTTP/1.x is a message whereas in HTTP/2 this would be a frame of a message. This allows HTTP/2 to transmit multiple messages "at once" (really: one frame of a given message at a time) while HTTP/1.1 could just start pipelining and possible suffer from HOL-blocking as you mentioned.
As for your question regarding multiple packets being sent simultaneously: Yes, that is possible and is also regularly done. That would concern wave physics, fourier transformations, and electrical engineering and thus be a bit off-topic for SO ;)
Can someone give me a concrete example of HTTP with/without pipelining? I always think that both methods can handle multiple requests/responses, except for pipelining case, it only uses one socket, which means only one connection. In contrast, without pipelining, each socket (connection) is unique to each request, so it has the overhead of opening/closing socket. However, with high speed internet today, the difference is negligible. Is that true?
No, even without pipelining, HTTP/1.1 will use a single socket for multiple requests; one after the other. And no, opening a new socket is expensive because it causes additional roundtrips.
Imagine I'm building an ordinary old website. Not a game, not a chat program, an ordinary website. Let's say it's a stack overflow clone.
The client side would simply make service calls to the server side. The server is essentially a dumb data store and never sends down HTML. The client handles all templating via javascript.
If I established a single websocket connection and did all requests through that, would I see a significant speedup over doing ajax requests?
The obvious advantage to using a single connection is that it only has to be established once. But how much time does that actually save? I know establishing a TCP connection can be costly, but in the grand scheme of things, does it matter?
I would not recommend websockets for webpages. HTTP 1.1 can reuse a TCP-connection for multiple requests, it's only HTTP 1.0 that had to use a new TCP connection for each request.
SPDY is probably a protocol that do what you are looking for. See SPDY: An experimental protocol for a faster web, but it's only supported by Chrome.
If you use websockets, the requests will not be cached.
One HTTP connection can only by used for one HTTP request at the same time. Say that a page requested a 100Kb document, nothing else will be send from the client to the server until that 100Kb document has been transferred. This is called head-of-line blocking. The client can establish an additional connection with the server, but there is also a limit on the amount of concurrent connections with the same server.
One of the primary reasons for developing SPDY and later HTTP/2 was solving this exact problem. However, support for SPDY and HTTP/2 is not yet as widespread as for WebSocket. WebSocket can get you there earlier because it supports multiple streams in full-duplex mode.
Once HTTP/2 is better supported it will be the preferred solution for this problem, but WebSocket will still be better for real-time web applications, where server needs to push data to the client.
Have a look at the N2O framework, it was created to address the problems I described above. In N2O WebSocket is used to send all assets associated with a page.
How much speed you could gain from using WebSocket instead of standard HTTP requests pretty much depends on your specific website: how often it requests data from the server, how big is a typical response, etc.
I always knew web browsers could do parallel downloads. But then the other day I heard about pipelining. I thought pipelining was just another name for parallel downloads, but then found out even firefox has pipelining disabled by default. What is the difference between these things and how do work together?
As I under stand it, "parallel downloads" are requests going out on multiple sockets. They can be to totally unrelated servers but they don't have to be.
Pipelining is an HTTP/1.1 feature that lets you make multiple requests on the same socket before receiving a response. When connecting to the same server, this reduces the number of sockets, conserving resources.
I think this MDC article explains HTTP pipelining pretty darn well.
What is HTTP pipelining?
Normally, HTTP requests are issued sequentially, with the next request being issued only after the response to the current request has been completely received. Depending on network latencies and bandwidth limitations, this can result in a significant delay before the next request is seen by the server.
HTTP/1.1 allows multiple HTTP requests to be written out to a socket together without waiting for the corresponding responses. The requestor then waits for the responses to arrive in the order in which they were requested. The act of pipelining the requests can result in a dramatic improvement in page loading times, especially over high latency connections.
Pipelining can also dramatically reduce the number of TCP/IP packets. With a typical MSS (maximum segment size) in the range of 536 to 1460 bytes, it is possible to pack several HTTP requests into one TCP/IP packet. Reducing the number of packets required to load a page benefits the internet as a whole, as fewer packets naturally reduces the burden on IP routers and networks.
HTTP/1.1 conforming servers are required to support pipelining. This does not mean that servers are required to pipeline responses, but that they are required to not fail if a client chooses to pipeline requests. This obviously has the potential to introduce a new category of evangelism bugs, since no other popular web browsers implement pipelining.
I recommend reading the whole article since there's more than what I copied into my answer.