socket.io - XHR polling vs flashsocket and websocket - websocket

I use node.js and socket.io.
I have a problem with the connection speed with socket.io.
In Internet Explorer and Opera I have a problem with the connection speed. - When I use flashsocket or websocket.
When I use the mode of transport-polling XHR connection is fast - in all browsers (IE, FF, Chrome, Opera).
What is the difference between the mode of transport - XHR-polling and flash / websocket?
What is the best mode of transportation? How to optimize the connection speed is socket.io?
Thanks for the advice!

I'd be surprised if the general speed of the connection over time was different between web browsers, but the reason you'll see a delay in the initial connection in Internet Explorer and in Opera is that native WebSocket support is not available as it's been disabled by default. So, if you choose FlashSocket then an additional Flash object (SWF file) will need to be downloaded before a connection is established.
WebSockets are being introduced in IE10 and in Opera they are available, but disabled by default.
What is the difference between the mode of transport - XHR-polling and flash / websocket?
XHR-polling - see http://en.wikipedia.org/wiki/Push_technology#Long_polling
FlashSocket connection - uses a Flash Socket object to establish a connection to the WebSocket server and communicates using the WebSocket protocol. This means there is interaction between Flash and JavaScript and also means an additional Flash object (SWF files) will need to be downloaded.
What is the best mode of transportation?
WebSockets for any Web Browser that natively supports it (Chrome, Firefox, Safari). If the Flash object (SWF file) is in the browser cache then connection should be fast. If it's not then there will be a delay. XHR Long-Polling is a good solution and will work cross browser but there are negatives:
between poll requests the data on display could be out of date (stale).
It's a less efficient connection method than a single TCP connection used by WebSockets since HTTP Long-Polling uses multiple connection to simulate bi-directional functionality
HTTP has an overhead which means additional header information is sent upon request and each subsequent request.
How to optimize the connection speed is socket.io?
(I'm pretty new to socket.io to this is just a suggestion)
I'd look at the configuring Socket.io docs and see if you can conditionally set the transports based on the browser that is connecting. Based on your experiences this could be:
Chrome, Firefox, Safari - WebSockets
IE, Opera - XHR-Polling

To reduce the time of connection, you can try to reduce the connect timeout (which is 10 seconds by default) using the "connect timeout" parameter.
For example, to reduce the connect timeout to 1 second:
socket = io.connect('http://your-site.com',{'connect timeout': 1000});

Related

WebSockets over HTTP/2, and GOAWAY

I am interested in how WebSockets over HTTP/2 work on browsers (Firefox, specifically, since that 's the only one I'm aware of which supports Websockets over H2) with GOAWAYs.
Now, I know that GOAWAYs are connection-level events, and if IIUC, a WebSocket/H2 connection is actually a single H2 stream which has been upgraded.
Let's say that we nowget a GOAWAY from the server - do we expect the browser to just close the H2 stream which was supporting the WebSocket connection with a CloseEvent with code 1001? Is there some other event which gets fired/which needs to be added to the WebSocket API, for eg, ongoaway?
Now, I know that GOAWAYs are connection-level events, and if IIUC, a WebSocket/H2 connection is actually a single H2 stream which has been upgraded.
A single HTTP/2 connection may have multiple HTTP/2 streams, each one possibly being a WebSocket over HTTP/2 "upgraded" stream (see this section).
The goal is to use one single TCP connection carry possibly multiple protocols, so a situation where some stream are normal HTTP/2 and some are WebSocket over HTTP/2 is possible.
When connection level GOAWAY is sent by the server, I would expect the client to react as specified in this section.
In particular the server may send a "graceful" GOAWAY, so clients don't open new streams.
When the server is about to send the GOAWAY, it should arrange to send a terminal (i.e. endStream=true) DATA frame containing a WebSocket Close frame, which would result in a CloseEvent in the browser.
I don't think any event should be added to browsers' WebSocket APIs, the transport over HTTP/2 should be completely transparent for client applications, like it is transparent using HTTP/1.1 or HTTP/2 when using XMLHttpRequest or fetch().

Will websockets over HTTP2 also be multiplexed in streams?

I am trying to clarify/understand whether websockets over HTTP/2 will also be multiplexed over a TCP connection using streams. Section 5 of RFC8441 seems to suggest it
After successfully processing the opening handshake, the peers should proceed with the WebSocket Protocol [RFC6455] using the HTTP/2 stream from the CONNECT transaction as if it were the TCP connection referred to in [RFC6455]. The state of the WebSocket connection at this point is OPEN, as defined by [RFC6455], Section 4.1.
The HTTP/2 stream closure is also analogous to the TCP connection closure of [RFC6455]. Orderly TCP-level closures are represented as END_STREAM flags ([RFC7540], Section 6.1). RST exceptions are represented with the RST_STREAM frame ([RFC7540], Section 6.4) with the CANCEL error code ([RFC7540], Section 7).
But my confusion arises from the fact that even with HTTP/1.1, while tabs in a browser share the underlying TCP connections (e.g. chrome makes 6 TCP connections) to the same host, creating a websocket to the same host in different tabs leads to distinct TCP connection in each tab.
I am not sure why the difference between the two & if it is likely to be the same for websockets over HTTP/2 as well.
Any experts out here who can clarify. Thanks.
But my confusion arises from the fact that even with HTTP/1.1, while tabs in a browser share the underlying TCP connections (e.g. chrome makes 6 TCP connections) to the same host, creating a websocket to the same host in different tabs leads to distinct TCP connection in each tab.
You are right that this is the current state of affairs, unfortunately, for HTTP/1.1.
RFC 8441, as you point out, has been specified to solve this problem and piggy back WebSocket "connections" over HTTP/2 streams, so it would be possible to open just one TCP connection to an origin server and use that connection for both HTTP/2 communication and for WebSocket communication.
The difference between HTTP/1.1 and HTTP/2 stems from the fact that HTTP/1.1 WebSocket connections cannot be (efficiently) pooled.
Every WebSocket connection is tied to a specific URI (e.g. ws://host/path1) and it's more typical for an application to open different WebSocket connections for different URIs (rather than many WebSocket connections for the same URI).
Because they cannot be pooled, browsers basically have to allow an unlimited number of them, a new one every time you call new WebSocket(...) from JavaScript.
With HTTP/2 instead, you will be able to open a new HTTP/2 stream inside the same HTTP/2 connection.
The number of concurrent streams depends on browser implementations, but it's typically around 100 if not more, which leaves plenty of concurrency for both HTTP/2 and WebSocket (unless the client application is really abusing WebSocket).
Fortunately, client applications won't need to be changed to leverage this feature.
When browsers and server will support it, your application will use less resources (just one TCP connection) rather than the many it's using now.
[Disclaimer, I'm the implementer of such feature in Jetty]
We have seen a few browsers implementing this feature and we are finalizing the implementation of this feature in the Jetty 10.0.x server, see https://github.com/eclipse/jetty.project/issues/3537.
creating a websocket to the same host in different tabs leads to distinct TCP connection in each tab
A WebSocket connection is always a new TCP connection, since it has to perform an HTTP/S request that Upgrades to a WebSocket connection and is therefore no longer an HTTP/S connection if successful. WebSocket connections are distinct and can't be shared or reused, unlike HTTP/S connections (assuming keep-alives are used).

Websockets in chrome devtools

Currently working with Socket.IO using websockets. I have a couple of questions regarding how to interpret websockets in the chrome devtools:
When we have the following output in chrome:
Questions:
The method still is specified with the HTTP get method verb. Is this because this HTTP protocol is used to initiate the handshake?
If we have 4 type = websocket like in this example. Do we actually have 4 websocket connections?
One websockets was completed and the other 3 were still pending, what does this mean?
Yes, that's because the WebSocket handshake is an HTTP GET request. As you can see in the Status column, the server responded with "101 Switching Protocols", after which the protocol changed to the WebSocket protocol.
You seem to have one closed connection and three ongoing connections. Maybe whatever library you're using likes to create multiple connections?
The "pending" connections are active connections. The developer tools shows each connection that hasn't been closed yet as "pending". Not the most clear representation, but the dev tools were made to primarily deal with HTTP where individual requests don't last forever.
Free ProTip in case you didn't know: If you click on any of the requests and then click on the Frames tab, you can see all the WebSocket messages in real-time.

Websockets and uwsgi - detect broken connections client side?

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.

How to establish a TCP Socket connection from a web browser (client side)?

I've read about WebSockets but they don't seem to be pure "sockets", because there is an application layer protocol over them. "ws:"
Is there any way of doing a pure socket connection from a web browser, to enliven webpages?
Here are my random stabs in the dark
Applets sockets provided by Java (need java installed)
Flash sockets provided by Flash (need flash installed)
But about HTML5, Why are they called WebSockets if they aren't Sockets?
Is the websocket protocol so simple to implement that it is "almost"-sockets?
I've read about WebSockets but they don't seem to be pure "sockets", because there is an application layer protocol over them.
[Is the] websocket protocol so simple to implement that [it is] "almost"-sockets?
Allowing regular socket connections directly from the browser is never going to happen because it opens up a huge risk. WebSockets is about as close to raw sockets from the browser as you are going to get. The initial WebSockets handshake is similar to an HTTP handshake (allowing web servers to proxy/bridge it) and adds CORS type security. In addition, WebSockets is a message based transport (rather than streaming as raw TCP) and this is done using a two byte header on each message frame.
Even flash is not able to quite make raw TCP connections. Flash sockets also add CORS security, but instead of an in-band handshake, flash socket connections make a connection to port 843 on the target server to request a security policy file.
Is there any way of doing a pure socket connection from a web browser, to enliven webpages?
Yes, you can use my websockify bridge/proxy which allows a WebSockets enabled browser to connect directly to a TCP socket via websockify.
But about HTML5, Why are they called WebSockets if they aren't Sockets?
WebSockets are a transport built on TCP sockets. After the handshake there is very minimal overhead (typically just a two byte header).
I can't improve on Kanaka's answers to your secondary questions, and I know this question is a year old. But for the main question, Is there any way of doing a pure socket connection from a web browser, to enliven webpages? There is a project called the Java / JavaScript Socket Bridge that might be what you (or anyone coming across this page from a Google search) are looking for. The advantage of this method over what others have mentioned is that it does not require either a client-side or a server-side service to be run. So, for instance, if you wanted to implement an IRC client purely in JavaScript but your web host does not allow you sufficient rights to proxy the connection, this Java applet would be the way to go. The only concern is making sure the client has Java installed and allowed.
You can just send data between a client and a server with WebSockets. Simply speaking, the only difference that WebSockets introduces is that the client:
adds some header bytes, like the type of data and the length
adds masks and encodes the data using them
The server also has to add header bytes, but does not need to encode the data.
If you implement the protocol correctly (server side, that is, since the browser already has an implementation), you can use it with ease to send text and binary data. (Although browser support is narrow, especially for the latter.)
The benefit of WebSocket is that it is HTTP based. You can use it also in environments there http proxies are used. Thus Websocket has a higher infrastructure compatibility as plain tcp.
Additionally http/WebSocket is providing you some features which you otherwise have to specify on your own:
Redirect
NAT keepalive
Multiplexing via URI
Framing
If you are asking for some data to be pushed from server it is widely termed as COMET or Reverse Ajax.
Web sockets is still not very popular as there are inherent firewall issues and minimal support yet from popular browsers.
You can take a look at http://www.ape-project.org/ as this is one of the most popular implementations (but native to unix/linux only for now. For windows they suggest using a virtual box or vmware based implementation)

Resources