Why do many websocket libraries implement their own application-level heartbeats? - node.js

For example socket.io has pingInterval and pingTimeout settings, nes for hapi has similar heartbeat interval settings. This is ostensibly to prevent any intermediates such as over-zealous proxies from closing what seems to be an inactive connection.
But ping/pong frames are part of the websocket protocol and seem to serve the same purpose. So why do websocket library implementors add another layer of ping/pong at the application level?
If I was pushed to guess it would be in case the websocket server is dealing with a client that doesn't respond/support the websocket protocol level ping-pongs.

I did some reading up and made some tests and I think it comes down to this:
Websocket pings are initiated by the server only
The browser Websocket API has isn't able to send ping frames and the incoming pings from the server are not exposed in any way
These pings are all about keepalive, not presence
Therefore if the server goes away without a proper TCP teardown (network lost/crash etc), the client doesn't know if the connection is still open
Adding a heartbeat at application level is a way for the client to establish the servers presence, or lack thereof. These must be sent as normal data messages because that's all the Websocket API (browser) is capable of.

Related

Difference in server port and websocket port in node.js chat application

I am trying to create a multi room chat application in node.js using socket.io and express. I am confused between use of server port and websocket port. I understand server port is used by the client to connect to server. But not sure about use of websocket port.
Thanks & Regards..
webSockets can share the same port as your web server and this is a common configuration. The reason this works is because of how a webSocket establishes a connection (all webSocket connections are initiated with an HTTP request). It works like this:
Client makes an HTTP request to a web server with a header specifying that they want to "upgrade" to the webSocket protocol and sends a security-related header.
Web server sees the upgrade request and, if it has support enabled for webSocket connections, it will respond with a 101 request (switching protocols) and another security related header.
Client gets the accepted upgrade and both ends switch to the webSocket protocol and the original TCP socket that started out using the HTTP protocol is now using the webSocket protocol.
In this manner, the same port and webServer can be used for regular HTTP requests or webSocket connection requests.
For a chat application it is common to use a webSocket connection because it is a continuous connection that more easily allows the server to send information directly to the client which is often needed in a chat application.
To understand more about how a webSocket connection and server work, see this reference on MDN: Writing WebSocket servers which shows the step by step process for initiating a webSocket connection.
Server socket is used by server... that keeps listening to coming sockets request in a loop... and websocket sends a request to server socket and bound a connection between two devices...
If you have / want to have web clients, WebSocket is going to be required, because there is no access to 'regular' TCP (or UDP) sockets from browser-based JavaScript (and I assume you do not want Flash, SilverLight or Java Applets, in 2017). WebSocket is not special because of the port number, but it is special because of the protocol: a WebSocket connection starts as a regular HTTP connection, and protocol upgrade reconfigures it afterwards, it is designed for the browser-world, and even capable of traversing HTTP proxies. After establishing the connection, it provides a full-duplex, bi-directional message stream, very usable for chat applications.
And because of being a Web-thing, you could simply use port 80, if you are allowed to.

When, if at all, is it more appropriate to use http over web sockets?

I am using Socket.IO with a MEAN stack and it's been excellent for low latency and bidirectional communication, but what would be the major draw back for using it for relatively static data as well as dynamic?
My assumption is that it would be more apt for sending more dynamic content. That being said, once a socket connection is established, how relevant is the amount of communication being done? Is there a time where it would be more appropriate to use http instead when a connection is constantly established throughout the user's direct interaction with the application?
Thanks!
WebSockets are a bidirectional data exchange within a HTTP connection. So the question is not if you use HTTP or WebSockets, because there is no WebSockets without HTTP. WebSockets are often confused with simple (BSD) sockets, but WebSockets are actually a socket-like layer inside a HTTP connection which is inside a TCP connection which uses "real" sockets. Or for anybody familiar with OSI layers: it as a layer 4 (transport) encapsulated inside layer 7 (application) and the main reason for doing it this strange way instead of using layer 4 directly is that plain sockets to ports outside of HTTP, SMTP and a few other protocols are no longer possible because of all the port blocking firewalls.
So the question should be more if you use simple HTTP or if you need to use WebSockets (inside HTTP).
With simple HTTP the client sends a request and the server sends the response back. The format is well defined and browser and server transparently support compression, caching and other optimizations. But this simple request-response pattern is limited, because there is no way to push data from server to client or to have a more (BSD) socket like behavior where both client and server can send any data at any time. There are various more or less good workarounds for this, like long polling.
WebSockets gives you a bidirectional communication, which makes it possible for the server to push data to the client or to send data in both directions at any time. And once the WebSocket connection is established by upgrading an existing HTTP connection the overhead for the data itself is very small, much smaller then with a full new HTTP request. While this sounds good you loose all the advantages of simple request-response HTTP like caching at the client or in proxies. And because client and server need resources to keep the underlying TCP connection open it needs more resources, which can be relevant for a busy server. Also, WebSockets might give you more trouble with middleboxes (like proxies or firewalls) then simple HTTP does.
In summary: if you don't need the advantages of WebSockets stay with simple request-response HTTP.

Socket.io constantly polling... should it be doing this?

I have a node server and a web page connected via socket.io. I noticed in the browser console that it is outputting
XHR finished loading: GET "http://my_url/socket.io/?EIO=3&transport=polling&t=1418944327412-412&sid=vqLTUtW3QhNLwQG8AAAA".
and
XHR finished loading: POST "http://my_url/socket.io/?EIO=3&transport=polling&t=1418944385398-415&sid=vqLTUtW3QhNLwQG8AAAA".
every few seconds. Should it be doing this or am I missing a setting. I'm really only looking to send data back and forth explicitly via the socket. Perhaps I'm missing something in the set up.
Client side is basically
var socket = io("http://my_url");
with the usual event listeners. Server side is
var io = require('socket.io')(server);
I tried placing this on the server side
io.set('transports', ['websocket']);
but that seemed to kill it.
The socket.io implementation (when using webSockets) sends regular (every few seconds) heartbeat and response packets to constantly verify that the connection is alive and well. This is normal.
These packets are not actual http requests (they are websocket data packets) so there should not be full-on http packets going on unless socket.io is not actually using the webSocket protocol, but is instead using HTTP long polling. socket.io will use the webSocket protocol as long as it is supported in the client (which it should be in all modern browsers nowadays).
You may have to be careful about how you interpret requests in a debugger. A socket.io connection starts its life as an http request with some custom headers and all debuggers will show this initial http request. If webSocket is supported at both ends, then the server will return a response which "upgrades" the connection to the webSocket protocol. That same TCP socket which started out as a TCP request, then becomes a webSocket connection. Subsequent webSockets messages sent on the webSocket then flow over that TCP socket. It is up to the debugger on how it might display that traffic. In the Chrome debugger, you have to open the original http connection and then ask to see websocket traffic and only then can you actually see webSocket packets. But, I could imagine in other debuggers that weren't as webSocket saavy, they might show subsequent packets as related to that original HTTP connection (I haven't looked at how debuggers other than Chrome show webSocket traffic).
The only other reason I can think of that a client would be repeatedly sending HTTP connection requests is if the connection keeps dropping for some reason so the client keeps reconnecting every time the connection drops. socket.io has settings that can control how often/vigorously the client tries to reconnect when the connection is lost, though if you have connection issues, then you really need to figure out why there are connection issues rather than change the reconnect settings.

Considering Web Socket for a JavaEE project

The requirements of the project are:
If any user updates a record (any record), all relevant parties must be notified immediately by displaying an alert somewhere in the webpage. In previous projects, the browser would poll the server for any relevant changes every N seconds.
I have been reading on web sockets and think this is the prefect solution for this problem (I do not like polling).
I have some questions regarding Web Sockets in JavaEE. Please correct me if I am wrong.
Web Socket seems to be supported on Glassfish server not in latest version of JBoss/Wildfly.
If 1000 clients are logged in and connected to the server using Web Socket, does the server have 1000 separate sockets open for each connection? Or is the implementation similar to Node.js where a single server socket is used for all client connections. This information does not seem to be documented anywhere in JavaEE tutorials.
Websockets are TCP connections and the websocket protocol is simply an upgrade of the TCP protocol with an handshake procedure similar to the http protocol, but the websocket protocol is bidirectional.
I don't think you are getting a single web socket in Node.js. You have a connection per logged client anyway. In Node.js you have the broadcast, but this is the same as sending a message to any logged client through the related web socket. You have the same functionality in glassfish, where you simply loop on all the web sockets:
http://www.byteslounge.com/tutorials/java-ee-html5-websockets-with-multiple-clients-example
and you can do the same in weblogic:
https://docs.oracle.com/middleware/1212/wls/WLPRG/websockets.htm#WLPRG872
This is the same as Node.js without any wrapper.

How to make the safest Websocket Authentication

I have seen this question answered a few times, but I have a very specific problem with it.
I am currently making a game, where a HTML5 programm is talking to a C++ programm on the server side. The game does also include matches with valuable prices and therefore the low latency between the client and the server as well as the security should be as high priority.
And that leads to my question: Is it safe enough to authenticate a websocket session (TLS encrypted) a single time when it is started or should I send the SESSIONID with every message send form the client to the server?
This question is very opinion based, and does not apply to the nature of questions of StackOverflow.
Here is my opinion:
WebSockets protocol is implemented on top of TCP network layer protocol which is connection based. So that means that connection is established and then persisted until it is closed by client or server. Interceptions in between are very unlikely possible.
After TCP connection is established WebSockets will send HTTP headers from client, just like any other HTTP request would do, but will not close connection, and wait for response from server, which is if everything "fine" header for approving HTTP protocol upgrade to WebSockets communication. Since then WebSockets are valid to be used on client and server side for communication. Since TCP connects it is persistent connection. So sending session for every request - is pointless, as it is sent once connection is established.
So no, it is not a good idea to send session details on every message as just pointless. You better make sure that restoring your session is secure process, and just obtaining cookies of a client - will not allow to connect as another user.

Resources