First let me explain the data flow I need
Client connects and registers with server
Server sends initialization JSON to client
Client listens for JSON messages sent from the server
Now all of this is easy and straightforward to do manually, but I would like to leverage a server of some sort to handle all of the connection stuff, keep-alive, dead clients, etc. etc.
Is there some precedent set on doing this kind of thing? Where a client connects and receives JSON messages asynchronously from a server? Without using doing manual socket programming?
A possible solution is known as Comet, which involves the client opening a connection to the server that stays open for a long time. Then the server can push data to the client as soon as it's available, and the client gets it almost instantly. Eventually the Comet connection times out, and another is created.
Not sure what language you're using but I've seen several of these for Java and Scala. Search for comet framework and your language name in Google, and you should find something.
In 'good old times' that would be easy, since at the first connection the server gets the IP number of the client, so it could call back. So easy, in fact, that it was how FTP does it for no good reason.... But now we can be almost certain that the client is behind some NAT, so you can't 'call back'.
Then you can just keep the TCP connection open, since it's bidirectional, just make the client wait for data to appear. The server would send whatever it wants whenever it can.... But now everybody wants every application to run on top of a web browser, and that means HTTP, which is a strictly 'request/response' initiated by the client.
So, the current answer is Comet. Simply put, a JavaScript client sends a request, but the server doesn't answer for a looooong time. if the connection times out, the client immediately reopens it, so there's always one open pipe waiting for the server's response. That response will contain whatever message the server want's to send to the client, and only when it's pertinent. The client receives it, and immediately sends a new query to keep the channel open.
The problem is that HTTP is a request response protocol. The server cannot send any data unless a requests is submitted by the client.
Trying to circumvent this by macking a request and then continously send back responses on the same, original, requests is flawed as the behavior does not conform with HTTP and it does not play well with all sort of intermediaries (proxies, routers etc) and with the browser behavior (Ajax completion). It also doesn't scale well, keeping a socket open on the server is very resource intensive and the sockets are very precious resources (ordinarly only few thousand available).
Trying to circumvent this by reversing the flow (ie. server connects to the client when it has somehting to push) is even more flawed because of the security/authentication problems that come with this (the response can easily be hijacked, repudiated or spoofed) and also because often times the client is unreachable (lies behind proxies or NAT devices).
AFAIK most RIA clients just poll on timer. Not ideal, but this how HTTP works.
GWT provides a framework for this kind of stuff & has integration with Comet (at least for Jetty). If you don't mind writing at least part of your JavaScript in Java, it might be the easier approach.
Related
I have a Nodejs application which is using Mysql as a database, express and passport to manage user authentication. There can be 20-30 users connected to my Nodejs application at once time.
Now, there are certain pages in my application where multiple users can work on the same stuff at once. So if one user changes the value of the field, the other user will also see that change. As of right now to achieve this I am just using a Setinterval function that is running every 5 seconds with an ajax request post to the Nodejs server and then redraw the user field if necessary. This is working fine till now, but now I have decided, I wanted other pages in my application that I want to work this way. This means there will be multiple post backs happening to my Nodejs server every seconds to run mysql query. I am kind of new to Nodejs and I am not sure if this is an optimal way to handle this situation.
I was wandering if there is a way to send new field data to client, without client request and redrawing the DOM for them.
There are two solutions built-into the browser for the server to send data directly to a connected client.
webSocket connections
Server sent events
With each of these technologies, the client establishes one of these two types of connections on any given web page and then the server is able to send the client data whenever it wants.
webSockets are two way communication channels. Server sent events are one-way (data sent from server to client). Server sent events were designed to be a bit more efficient, but are more limited in what they can do.
It's important to realize that the lasting connection between client and server is only for the duration of that current page in the browser. If the end-user switches to another web page (even another page on your site), then the browser will close your current connection. If that new web page wants a similar connection, then it establishes a new connection on the new page.
With these types of connections from browser to server, your server then keeps track of each connection and some identifying information for each connection (like a username or userID). Then, when something changes in the data on the server, your server can figure out which clients should be notified of that change and send that new data over their connection. The client then receives that data and updates the visuals of the webpage using Javascript (displaying new data, updating status, etc...).
FYI, there is also a popular library called socket.io that works on top of webSocket and adds a number of useful features outlined here (such as connection failure detection, auto-reconnect, message passing layer, etc...). You would use the socket.io library in both client and server to add these features.
I have a realtime HTML5 canvas game that runs off a node backend. Players are connected via Websocket (socket.io). The problem is sometimes I need to deploy new code (hotfixes for instance) and restart the server but I don't want to disconnect players.
My idea for this was to divide the websocket server and application server into separately deployable components and add a message queue in the middle to decouple the 2 components. That way if the application server was rebooting there would just be a short delay while the messages bunch up but nothing would be lost. Is this a good strategy? Is there an alternative?
It's very possible for websocket based applications to be restarted without the user noticing anything (that's the case for my chat server for example).
To make that possible, the solution isn't to have a websocket application isolated and never restarted. In fact this would be very optimistic (are you sure you could ensure its API is never changed ?).
A solution is
to ensure the client reconnects if disconnected (this is standard if you use socket.io for websocketing)
to make the server ask the client its id (or session id) on client initiated reconnection
to persists the state of the application. This is usually done with a database. If your server has no other state than the queue between clients (which is a little unlikely) then you might look for an existing persistent queue implementation or build your own over a fast local storage (redis comes to mind)
I am basically writing an almost purely clientside application (there is a webserver which can be used to store some persistent data, but its easier to forget about it), but as part of this I was looking to add some functionality akin to hosting a game.
The scenario would be 1 person would host the game via their browser (open a TCP socket awaiting connections), then X other people would connect to that server and join. The server would be in charge of receiving and sending data between clients.
So in this scenario is it possible to host a websocket server within a webpage?
I was looking at trying to do something peer to peer style, but I don't think it is currently supported, but its not a major problem as its only going to be for sending small amounts of text and some update messages between clients.
The WebSocket browser API is client only (for the foreseeable future).
In some sense, WebRTC us peer-to-peer, but even if the WebRTC API adds the ability to send arbitrary data, you still need a STUN/TURN server to establish the initial connection.
This can be any type of data feed, let's just say for this example stock market data since that's a popular one. But I'm talking about real time data feeds. So it continuously sends data.
I'm trying to understand how this is implemented. Does this happen in some way over http? I just don't get how the clients hook up to the server and the server sends continuous data, can anyone clue me into how this works technically? How might a client hook up to the server? Let's take C# or Java or something. Does this happen over http or maybe some other type of way? please go into details.
Thanks
It's not really any different from normal HTTP traffic, just longer.
What happens when you open a website? (very rough overview)
Your computer contacts a server, establishes a connection.
Server starts sending data split into packets to you.
Your computer receives the packets, possibly out-of-order and some with significant delay, and re-assembles them into a website.
Your computer sends an acknowledgment for received packets.
The server will retransmit any packets it hasn't received an acknowledgment for for a significant amount of time, assuming they were dropped on the way.
In between receiving packets and/or acknowledgments, both wait.
When all data necessary for displaying the site is transferred, your computer thanks the server for its time and disconnects.
If at any point in this process either party stops responding for a significant amount of time, either side may drop the connection, assuming technical difficulties.
What's happening with "streaming data feeds"? (even rougher overview)
A client contacts a server, establishing a connection.
The server starts sending data split into packets to the client.
The client receives the packets, possibly out-of-order and some with significant delay, and re-assembles them.
The client sends an acknowledgment for received packets.
The server will retransmit any packets it hasn't received an acknowledgment for for a significant amount of time, assuming they were dropped on the way.
In between receiving packets and/or acknowledgments, both wait.
The only difference is that the client doesn't hang up on the server, because it's still expecting data and that both aren't as quick to drop the connection.
The thing is that web servers (for web sites) are specialized for the task of delivering small snippets of data to many people, so they're quick to hang up on you once all data has been sent. Your server script can simply not quit though, and the connection will stay alive. Here's a tiny PHP script that will demonstrate that:
while (true) {
echo '.';
sleep(1);
}
This will send a new . every second indefinitely (note that the web server needs to be configured appropriately to not terminate the script and to immediately send the output).
Try the Wikipedia article about TCP/IP for the basics and this article about long-polling/HTTP streaming for concrete examples.
I have one app. that consists of "Manager" and "Worker". Currently, the worker always initiates the connection, says something to the manager, and the manager will send the response.
Since there is a LOT of communication between the Manager and the Worker, I'm considering to have a socket open between the two and do the communication. I'm also hoping to initiate the interaction from both sides - enabling the manager to say something to the worker whenever it wants.
However, I'm a little confused as to how to deal with "collisions". Say, the manager decides to say something to the worker, and at the same time the worker decides to say something to the manager. What will happen? How should such situation be handled?
P.S. I plan to use Netty for the actual implementation.
"I'm also hoping to initiate the interaction from both sides - enabling the manager to say something to the worker whenever it wants."
Simple answer. Don't.
Learn from existing protocols: Have a client and a server. Things will work out nicely. Worker can be the server and the Manager can be a client. Manager can make numerous requests. Worker responds to the requests as they arrive.
Peer-to-peer can be complex with no real value for complexity.
I'd go for a persistent bi-directional channel between server and client.
If all you'll have is one server and one client, then there's no collision issue... If the server accepts a connection, it knows it's the client and vice versa. Both can read and write on the same socket.
Now, if you have multiple clients and your server needs to send a request specifically to client X, then you need handshaking!
When a client boots, it connects to the server. Once this connection is established, the client identifies itself as being client X (the handshake message). The server now knows it has a socket open to client X and every time it needs to send a message to client X, it reuses that socket.
Lucky you, I've just written a tutorial (sample project included) on this precise problem. Using Netty! :)
Here's the link: http://bruno.linker45.eu/2010/07/15/handshaking-tutorial-with-netty/
Notice that in this solution, the server does not attempt to connect to the client. It's always the client who connects to the server.
If you were thinking about opening a socket every time you wanted to send a message, you should reconsider persistent connections as they avoid the overhead of connection establishment, consequently speeding up the data transfer rate N-fold.
I think you need to read up on sockets....
You don't really get these kinds of problems....Other than how to responsively handle both receiving and sending, generally this is done through threading your communications... depending on the app you can take a number of approaches to this.
The correct link to the Handshake/Netty tutorial mentioned in brunodecarvalho's response is http://bruno.factor45.org/blag/2010/07/15/handshaking-tutorial-with-netty/
I would add this as a comment to his question but I don't have the minimum required reputation to do so.
If you feel like reinventing the wheel and don't want to use middleware...
Design your protocol so that the other peer's answers to your requests are always easily distinguishable from requests from the other peer. Then, choose your network I/O strategy carefully. Whatever code is responsible for reading from the socket must first determine if the incoming data is a response to data that was sent out, or if it's a new request from the peer (looking at the data's header, and whether you've issued a request recently). Also, you need to maintain proper queueing so that when you send responses to the peer's requests it is properly separated from new requests you issue.