I am reading a lot about HTML5 and I like the web sockets in particular because they facilitate bi-directional communication between web server and web browser.
But we keep reading about chrome, opera, firefox, safari getting ready for html5. Which web server is ready to use web sockets feature? I mean, are web servers capable of initiating subsequent communication as of today? How about Google's own Appengine?
How can I write a sample web application that takes advantage of this feature in Java?
Bi-directional communication between web servers and browsers is nothing new. Stack Overflow does it today if a new answer is posted to a question you're reading. There are a few different strategies for implementing socket-style behavior using existing technologies:
AJAX short polling: Connect to the server and ask if there are any new messages. If not, disconnect immediately and ask again after a short interval. This is useful when you don't want to leave a lot of long-running, idle connections open to the server, but it means that you will only receive new messages as fast as your polling interval, and you incur the overhead of establishing a new HTTP connection every time you poll.
AJAX long polling: Connect to the server and leave the connection open until a new message is available. This gives you fast delivery of new messages and less frequent HTTP connections, but it results in more long-running idle processes on the server.
Iframe long polling: Same as above, only with a hidden iframe instead of an XHR object. Useful for getting around the same-origin policy when you want to do cross-site long polling.
Plugins: Flash's XMLSocket, Java applets, etc. can be used to establish something closer to a real low-level persistent socket to a browser.
HTML5 sockets don't really change the underlying strategies available. Mostly they just formalize the strategies already in use, and allow persistent connections to be explicitly identified and thus handled more intelligently. Let's say you want to do web-based push messaging to a mobile browser. With normal long-polling, the mobile device needs to stay awake to persist the connection. With WebSockets, when the mobile device wants to go to sleep, it can hand off the connection to a proxy, and when the proxy receives new data it can wake up the device and pass back the message.
The server-side is wide open. To implement the server-side of a short polling application, you just need some kind of a chronological message queue. When clients connect they can shift new messages off the queue, or they can pass an offset and read any messages that are newer than their offset.
Implementing server-side long polling is where your choices start to narrow. Most HTTP servers are designed for short-lived requests: connect, request a resource, and then disconnect. If 300 people visit your site in 10 minutes, and each takes 2 seconds to connect and download HTTP resources, your server will have an average of 1 HTTP connection open at any given time. With a long polling app, you're suddenly maintaining 300 times as many connections.
If you're running your own dedicated server you may be able to handle this, but on shared hosting platforms you're likely to bump up against resource limits, and App Engine is no exception. App Engine is designed to handle a high volume of low latency requests, e.g. short polling. You can implement long polling on App Engine, but it's ill-advised; requests that run for longer than 30 seconds will get terminated, and the long running processes will eat up your CPU quota.
App Engine's solution for this is the upcoming Channel API. The channel API implements long polling using Google's existing robust XMPP infrastructure.
Brett Bavar and Moishe Lettvin's Google I/O talk lays out the usage pattern as follows:
App Engine apps create a channel on a remote server, and are returned a channel ID which they pass off to the web browser.
class MainPage(webapp.RequestHandler):
def get(self):
id = channel.create_channel(key)
self.response.out.write(
{'channel_id': id})
The web browser passes the channel ID to the same remote server to establish a connection via iframe long polling:
<script src='/_ah/channel/jsapi'></script>
<script>
var channelID = '{{ channel_id }}';
var channel =
new goog.appengine.Channel(channelId);
var socket = channel.open();
socket.onmessage = function(evt) {
alert(evt.data);
}
</script>
When something interesting happens, the App Engine app can push a message to the user's channel, and the browser's long poll request will immediately receive it:
class OtherPage(webapp.RequestHandler):
def get(self):
# something happened
channel.send_message(key, 'bar')
Jetty, for example, supports this feature since version 7: Jetty Websocket Server
Google App Engine have plans for this also. They even have working demo of this at Google I/O 2010, but it's not in production yet. See ticket #377
Related
I have a Windows application (written in Java) that connects to the server (spring + httpd) via websockets. Another websocket connection is established as soon as a user authenticates to the same server from a web browser. If server notice that both clients have same IP address, it "pairs" them so both applications can talk with each other.
The challenge I'm facing currently is that when multiple Windows application are starting up, all of them establish new websocket connections that exceeds httpd limitation of 255 active connections and the server goes down.
I'm looking for some feasible solution that would not overwhelm the server. A perfect scenario: a user logs into the system using a web browser, the server tries to connect the Windows application running on a clients machine afterwards and everyone is happy.
Have you any idea how to achieve it?
What I've tried already is to not create a new websocket connection on the Windows application startup but send a GET request to the request to the server and wait for the response that will occur after authenticating a user from a web browser. Hanging GET requests still need resources and httpd keeps a separate process for each of them. Also, it turned out that httpd has a 5 minutes timeout for hanging requests and sends 502 back after reaching it out.
I thought that maybe it is possible to handle GET requests in Spring by only one process / thread, but I haven't found any info for that.
Another limitation worth noting is that the Windows application runs on customer machines and customer's security policy may not allow for any wise tricks.
I tried reading some articles, but not so clear on this topic.
Would someone like to explain me below points:
Why use websocket over http
what is full duplex communication
what do you mean by lower latency interaction
Why use websocket over http?
A webSocket is a continuous connection between client and server. That continuous connection allows the following:
Data can be sent from server to client at any time, without the client even requesting it. This is often called server-push and is very valuable for applications where the client needs to know fairly quickly when something happens on the server (like a new chat messages has been received or a new price has been udpated). A client cannot be pushed data over http. The client would have to regularly poll by making an http request every few seconds in order to get timely new data. Client polling is not efficient.
Data can be sent either way very efficiently. Because the connection is already established and a webSocket data frame is very efficiently organized (mostly 6 extra bytes, 2 bytes for header and 4 bytes for Mask), one can send data a lot more efficiently than via a HTTP request that necessarily contains headers, cookies etc...
what is full duplex communication?
Full duplex means that data can be sent either way on the connection at any time.
what do you mean by lower latency interaction
Low latency means that there is very little delay between the time you request something and the time you get a response. As it applies to webSockets, it just means that data can be sent quicker (particularly over slow links) because the connection has already been established so no extra packet roundtrips are required to establish the TCP connection.
For a comparison in what's involved to send some data via an http request vs. an already established webSocket connection see the steps listed in this answer: websocket vs rest API for real time data?
These other references may also be useful:
Server-push whenever a function is called: Ajax or WebSockets
For a push notification, is a websocket mandatory?
HTML5 WebSocket: A Quantum Leap in Scalability for the Web
I have a web application and a web-service that needs to communicate with each other. This communication has to be a two way communication because web-application can send events occured at interface to web-service. And web-service can send the events recieved by third party to web-application part. So, what design should I follow for doing this? How to make this communication a two-way communication?
Regards,
Anshul
You can do this by employing the Comet model (called sometimes reversed AJAX).
It is implemented by long-polling or opening a persistent connection to the webservice.
In long-polling mode, the client opens a connection to the webservice and waits for the server's response. When there is an event coming from the server to the client, the server simply responds using that pre-existing connection and closes the connection, then the client reads the response, and immediately opens a new connection to listen for more events.
In the streaming mode, the connection is persistent, not closed after each server event. HTTP/1.1 chunked responses with hidden iframe can be used to accomplish this.
Regardless of the client-side implementation, beware using Comet may cause an excessive number of open connections on the server side. You should take that into account when deciding on the web-server stack / web framework - ideally it should use non-blocking I/O and continuations to decouple long connections from server's threads.
Some web frameworks have Comet support already built in: Play and Lift
I am looking to build an instant messenger in Java.
Clients will connect to the server to log in.
They will start a conversation with one or more other clients.
They will then post messages to the server that will relay the messages to all the clients.
The client needs to be continually updated when users post messages or log in.
so the way I see it, the client needs to run a server itself in a separate thread so that the main server can send stuff to it. Otherwise the client will have to the poll the main server every xyz seconds to get the latest updates. And that would need a separate thread anayway, as that would be purely for getting updates whereas the 'main' thread would be used for when the client initiates actions such as posting messages/inviting others to conversations etc...
So anyone recommendations on how to write this instant messenger? Does it sound like a good idea to make the connection a 'two-way' connection where both the client and server act as servers? Or is polling a better option? Anyone know how the IRC protocol does this?
There's no real advantage of having 2 connections unless they can be handled independently (for example receiving / sending a file usually done in a separate connection). A connection itself is already a two-way communication channel so it can be used to both send and receive messages, events etc. You don't need to poll server since client is able to maintain persistent connection and just wait for data to appear (optionally sending periodic PING-like message to ensure connection is alive).
IRC uses a single connection to server to exchange text commands. For example one of the main commands:
PRIVMSG <msgtarget> <message>
This command can be originated either by client or by server. Client sends PRIVMSG to notify that it wants to deliver message to one or more destination (in IRC this either user(s) or channel(s)). Server's task here is to properly broadcast this message to appropriate clients.
If you're using raw InputOutput streams then yes this is a good way of doing it. You create one thread on the clientside that acts in a similar fashion as the server thread - waits for any incoming updates and when it does it updates the client. I wouldn't call it a server though. So you'd ideally have 2 TCP/UDP connections one for requests made by the client and one to notify the client of server changes.
This solution in an enterprise environment would probably be done through some kind of messaging framework such as Spring Integration but dig deep enough and it will essentially be a similar way to how you mentioned.
Do you need a fully custom protocol or would it be sufficient to use the XMPP? There are several open source libraries implementing XMPP.
http://xmpp.org/xmpp-software/libraries/
e.g. http://www.igniterealtime.org/projects/smack/
For me, to develop instant messaging service, I will use websocket protocol instead of normal java socket because the normal socket can not work well with HTTP protocol and moreover some network providers and firewalls banned custom ports. If you develop it in normal socket, your service could not be accessed by web clients.
Did you plan to develop the instant messaging service yourself? How about using other protocols such as Jabber?
I have a J2ME app running on my mobile phone(client),
I would like to open an HTTP connection with the server and keep polling for updated information on the server.
Every poll performed will use up GPRS bytes and would turn out expensive in the long run, as GPRS billing is based on packets sent and received.
Is there a byte efficient way of polling using the HTTP protocol?.
I have also heard of long polling, But I am not sure how it works and how efficient it would be.
Actually the preffered way would be for the Server to tell the phone app that new data is ready to be used that way polling won't be needed to be done, however I don't know of these techniques especially in J2ME.
If you want solve this problem using HTTP only, long polling would be the best way. It's fairly easy. First you need to setup an URL on server side for notification (e.g. http://example.com/notify), and define a notification protocol. The protocol can be as simply as some text lines and each line is an event. For example,
MSG user1
PHOTO user2 album1
EMAIL user1
HEARTBEAT 300
The polling thread on the phone works like this,
Make a HTTP connection to notification URL. In J2ME, you can use GCF HttpConnection.
The server will block if no events to push.
If the server responds, get each line and spawn a new thread to notify the application and loopback to #1.
If the connection closes for any reason, sleep for a while and go back to step 1.
You have to pay attention to following implementation details,
Tune HTTP timeouts on both client and server. The longer the timeout, the more efficient. Timed out connection will cause a reconnect.
Enable HTTP keepalive on both the phone and the server. TCP's 3-way handshake is expensive in GPRS term so try to avoid it.
Detect stale connections. In mobile environments, it's very easy to get stale HTTP connections (connection is gone but polling thread is still waiting). You can use heartbeats to recover. Say heartbeat rate is 5 minutes. Server should send a notification in every 5 minutes. If no data to push, just send HEARTBEAT. On the phone, the polling thread should try to close and reopen the polling connection if nothing received for 5 minutes.
Handling connectivity errors carefully. Long polling doesn't work well when there are connectivity issues. If not handled properly, it can be the deal-breaker. For example, you can waste lots of packets on Step 4 if the sleep is not long enough. If possible, check GPRS availability on the phone and put the polling thread on hold when GPRS is not available to save battery.
Server cost can be very high if not implemented properly. For example, if you use Java servlet, every running application will have at least one corresponding polling connection and its thread. Depending on the number of users, this can kill a Tomcat quickly :) You need to use resource efficient technologies, like Apache Mina.
I was told there are other more efficient ways to push notifications to the phone, like using SMS and some IP-level tricks. But you either have to do some low level non-portable programming or run into risks of patent violations. Long polling is probably the best you can get with a HTTP only solution.
I don't know exactly what you mean by "polling", do you mean something like IMAP IDLE?
A connection stays open and there is no overhead for building up the connection itself again and again. As stated, another possible solution is the HEAD Header of a HTTP Request (forgot it, thanks!).
Look into this tutorial for the basic of HTTP Connections in J2ME.
Pushing data to an application/device without Push Support (like a Blackberry) is not possible.
The HEAD HTTP request is the method that HTTP provides if you want to check if a page has changed or not, it is used by browsers and proxy servers to check whether a page has been updated or not without consuming much bandwidth.
In HTTP terms, the HEAD request is the same as GET without the body, I assume this would be only a couple hundred bytes at most which looks acceptable if your polls are not very frequent.
The best way to do this is to use socket connection. Many application like GMail use them.