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.
Related
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.
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.
This question already has answers here:
WebSockets protocol vs HTTP
(6 answers)
Closed 8 years ago.
when I read engine io protocol, I found it use polling to establish the connection and then upgrade the transport to websocket, I don't know why ? could you give me some idea?
It's because the WebSocket upgrade could fail, so having polling as a fallback mechanism is useful.
It doesn't really use polling. The initial HTTP url may look like it's a setup for polling, but that will go into play only if the server doesn't agree to upgrade the connection to the webSocket protocol.
A socket.io connection starts with a single TCP connection which is an HTTP request with certain webSocket headers set and then when the server responds that the webSocket protocol is supported, the connection is "upgraded" from HTTP to webSocket and both sides switch the protocol being used from HTTP to webSocket. This is how the webSocket protocol is specified.
If the client/server combination does not support webSocket, then and only then does socket.io resort to using long polling.
This particular design allows both webSocket and HTTP to share the same port and the socket.io design allows for a graceful fallback to long-polling if both sides don't agree on a webSocket upgrade.
engine.io/socket.io 1.x+ starts with polling first because that pretty much always works with all types of clients, allowing them to get connected very quickly. Then in the background, attempts to upgrade the connection are made (to WebSockets or whatever else). That way if the connection upgrades fail, nothing is lost because the polling is still working like before, so there is no down time.
The reason for this change from the old behavior of downgrading instead of upgrading is that WebSockets can be troublesome to get going correctly in some situations (e.g. problems with load balancers, proxies, etc.) and even if they do get connected there can be some extra delays involved. Also using the flash fallback for WebSockets would take some time to get connected because it involves extra roundtrips and some additional delays.
I am developing a WebSocket service using NodeJS and Einaros WS module and I have raised this question: NodeJS Einaros WS Connection Timeout which apparently no one know the answer so I presume I should write my own ping pong based system to check whether a client is still connected or not.
I am not sure whether I should write code on server side or client side; I mean if the server should ping the client or... the client (which is my own websocket application) should ping the server.
Is there any difference between both methods ?
It is called a heartbeat and is usually sent by the client every 5 seconds with a ping frame (0x09) as opcode while the server responds with a pong frame (0xA) as opcode.
In theory it doesn't really matter whether it's the server or client initiating the heartbeat, but in a real-world situation it is usually better that the client keep itself updated whether the server is there or not to be able to inform the user as quickly as possible.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I was reading a lot about nodejs but still not clear about following :
With TCP protocol client and server agree on one port and then can maintain a connection. Server knows IP address of client and hence can send back messages. If we use nodejs then multiple clients can connect to same nodejs server on same port. How this can be possible? How multiple connections can be established on same port by same server.
If client is behind NAT then its IP can be dynamic, so how can nodejs server can send data to client.
What will be resource utilization in maintaining persistent connections on server and client ?
What happend when nodejs server crashes? How can client initiate connection again ?
If there is network problem on client side and it terminates and initiate connection after every 5 mins ..then is there a way this scenario can be handled?
With TCP protocol client and server agree on one port and then can maintain a connection.Server knows IP address of client and hence can send back messages.If we use nodejs then multiple clients can connect to same nodejs server on same port. How this can be possible? How multiple connections can be established on same port by same server.
There is no limitation to the number of connections which can be maintained on a single port (although, in practice, there may be operating system or hardware limitations). Of course, only a single process can listen on a port, but that has nothing to do with connections. That's not node-specific, all TCP servers work like that.
If client is behind NAT then its IP can be dynamic , so how can nodejs server can send data to client.
You're essentially asking how NAT works. Again, there's nothing node-specific in this case. The NAT server simply alters packet headers as necessary, and maintains translation tables for routing, just like with any connection.
What will be resource utilization in maintaining persistent connections on server and client
The overhead is really quite minimal for just the connection itself. A little bit of memory, but almost insignificant in the big picture. If you're storing additional associated data with each connection, that may be different. Node.js handles large number of concurrent connections very well, but if you're concerned, you can always search for benchmark tests, or write your own.
What happend when nodejs server crashes?How can client initiate connection again?
Sockets emit both close and error events. Simply listen for them, and attempt to reconnect afterwards, probably with a back-off delay.
If there is network problem on client side and it terminates and initiate connection after every 5 mins ..then is there a way this scenario can be handled?
Not entirely sure what you're asking here. The client simply needs to reconnect as stated in the previous question/answer. If you're associating certain data with a client socket, and you want a grace period where the client has a chance to reconnect before that data is freed, then you'll need to set a timeout which will free those resources after a certain amount of time. Then, in the connection listener, or perhaps on an authentication event, you'll want to analyse the new connection to see if it matches a recently disconnected client.
I would definitely recommend looking at socket.io, especially if your use case is web-based, although it can be used for more than just browser/server connections. It will do a lot of the things you seem to be concerned about (reconnection, resource association, disconnect grace period, etc) more or less automatically.
TCP connection is kept continously open. Saving is achieved by client not having to continously refresh from server in a long pooling manner in order to check if there are any new messages on the server like in case of AJAX. Creating a new connection every couple of seconds for client to refresh from server is heavy on the server, proxies and routers. In case of Node.js connection is kept open, but it is not active until the client or server have something to send. Found good article here http://www.html5rocks.com/en/tutorials/websockets/basics/
Imagine having a 1000 chat clients and each of them asks server every 3 seconds if any new messages arrived. That results in 2000 requests and responses per minute on the server. In case of Node.js server will send message to client only when there is a message to send, while all 1000 connections will be idle in the meantime, but will be kept open.
TCP connections are always initiated on the same port like port 80, but communication is maintaines on different ports assigned to each connection when it is open. So you would still need to keep connections continously open, but you will not have to send pooling messages continously like you needed before.