Jetty WebSocket Server

Posted on November 23, 2009 by gregw

Jetty-7.0.1 has been extended with a WebSocket server implementation based on the same scalable asynchronous IO infrastructure of Jetty and integrated into the Jetty Servlet container.

WebSocket came out of work on HTML5 by the  What Working Group to specify a mechanism to allow two way communications to a browsers.  It is currently being standardized at the W3C for the WebSocket API and by the IETF for the WebSocket protocol and is soon to be supported by releases of Firefox, and Chromium. While I have significant concerns about the websockets protocol, it is important that server concerns are considered in the standardization process. Thus to follow the IETF model of “rough consensus and working code”, it is important that Jetty has a working implementation of the protocol.

The key feature of the Jetty Websocket implementation is that it is not another separate server.  Instead it is fully integrated into the Jetty HTTP server and servlet container. so a Servlet or Handler can process and accept a request to upgrade a HTTP connection to a WebSocket connection.    Applications components created by standard web applications can then send and receive datagrams over the WebSocket with non blocking sends and receives.

Below is an example of a SIMPLE “Chat” application written using the Jetty WebSocketServlet, which can handle normal doGet style requests, but will call doWebSocketConnect if an upgrade request is received:

public class WebSocketChatServlet extends WebSocketServlet{    private final Set _members = new CopyOnWriteArraySet();

    protected void doGet(HttpServletRequest request, HttpServletResponse response)         throws ServletException ,IOException     {        getServletContext().getNamedDispatcher("default").forward(request,response);    }

    protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)    {        return new ChatWebSocket();    }

    class ChatWebSocket implements WebSocket    {        Outbound _outbound;

        public void onConnect(Outbound outbound)        {            _outbound=outbound;            _members.add(this);        }

        public void onMessage(byte frame, byte[] data,int offset, int length)        {}

        public void onMessage(byte frame, String data)        {            for (ChatWebSocket member : _members)            {                try                {                    member._outbound.sendMessage(frame,data);                }                catch(IOException e) {Log.warn(e);}            }        }

        public void onDisconnect()        {            _members.remove(this);        }    }}

The client side of this chatroom is implemented by this script, whose key sections include:

join: function(name) {  this._username=name;  var location = document.location.toString().replace('http:','ws:');  this._ws=new WebSocket(location);  this._ws.onopen=this._onopen;  this._ws.onmessage=this._onmessage;  this._ws.onclose=this._onclose;},_onopen: function(){  $('join').className='hidden';  $('joined').className='';  $('phrase').focus();  room._send(room._username,'has joined!');},_send: function(user,message){  user=user.replace(':','_');  if (this._ws)    this._ws.send(user+':'+message);},_onmessage: function(m) {  if (m.data){    var c=m.data.indexOf(':');    var from=m.data.substring(0,c).replace('<','<').replace('>','>');    var text=m.data.substring(c+1).replace('<','<').replace('>','>');    ...              }      }

This example is included in the test webapp shipped with Jetty-7.0.1,  and has been tested with the websocket client in dev releases of Google Chromium 4.0.

The intention for the jetty-websocket server is to be the focus of trial and experimentation with the protocol, it’s implementation and framesworks like cometd that might use it. All should be considered Alpha and highly likely that they will change with feedback received. Hopefully using the protocol with real servers, clients and applications will result in the experience required to feedback to the IETF requirements that will drive the improvement of the protocol.

One example of an area that needs to be improved is the discovery and/or negotiation of idle timeouts for the WebSocket connections.   Currently the jetty-server is inheriting the idle timeout of the HTTP connection, which is 30s by default.  This means that the demo chat application drops it’s connection after 30 seconds of no conversation.  This is not exactly what you want in a chat room, but because there is no way to discover or configure the idle timeouts of other parties to a websocket connection (including proxies), then the application has no choice but to handle the idle close event itself.

This entry was posted in General. Bookmark the permalink.

22 comments on “Jetty WebSocket Server

  1. spacer Tony Maley on said:

    Fantastic timing on this! this is what we all need, even if most of us don’t know it yet – great work guys.

    Reply
  2. spacer uberVU - social comments on said:

    [Trackback] This post was mentioned on Twitter by EclipsePlanet: Greg Wilkins: Jetty WebSocket Server bit.ly/91Loxz

    Reply
  3. spacer Patrick Mueller on said:

    Great news!
    I can’t seem to find a (binary) download for this. And where should discussion take place?

    Reply
  4. spacer Greg Wilkins on said:

    Patrick, sorry my blog was a day premature. We are just staging the release now. Discussion should be on jetty-dev@eclipse.org for our implementation or on hybi@ietf.org for the actual protocol itself.

    Reply
  5. spacer Tor Atle Lunde on said:

    Grabbed the latest Chromium I could find (33214 / 4.0.223.16), but I get “Websocket not supported by this browser” when trying out the ws chat-app.

    Reply
  6. spacer Tor Atle Lunde on said:

    Grabbed the latest Chrome I could find (33214 / 4.0.223.16), but I get “Websocket not supported by this browser” when trying out the ws chat-app.

    Reply
  7. spacer Greg Wilkins on said:

    I’m using a nightly build of chromium and it reports: 4.0.252.0 (32473) and I got it from build.chromium.org/buildbot/snapshots/
    So perhaps 4.0.223 is too early.

    Reply
  8. spacer Tor Atle Lunde on said:

    Thanks, Greg. I’ll try again tomorrow. This is all very exciting.

    Reply
  9. spacer Robert Adamsky on said:

    When running this with latest download version of Jetty 7.0.1 with Chromium 4.0.253.0 (0) get an NPE during the processing of the following line in WebSocketServlet (line 58):
    HttpConnection http = HttpConnection.getCurrentConnection();

    Reply
  10. spacer Tor Atle Lunde on said:

    I’ve tested Cometd for a while, and the most noticeable improvement is the ability to have multiple browsers (clients) running at the same time without any fallback to polling. Looking good so far, appreciate the effort!

    Reply
  11. spacer Patrick Mueller on said:

    I just tried the version of Jetty 7.0.1.v20091125 from dist.codehaus.org/jetty/jetty-7.0.1/ and the sample now works. I wasn’t able to find the same download at eclipse.org though.

    Reply
  12. spacer Mia Lefevre on said:

    Does anyone know of any python websocket client libraries to test WebSocket?

    Reply
  13. spacer Mia Lefevre on said:

    I am getting the following when using 4.0.270 (34447), Any ideas?
    Bad Upgrade header: Connection: Upgrade
    Set-Cookie: JSESSIONID=1d91u9kj2p7vm;Path=/
    Set-Cookie: uuid=580316a9-3f4e-4fbf-9c67-f0902ade383f;Path=/;Domain=XXXXX.com;Expires=Tue, 14-Dec-10 14:19:26 GMT
    Upgrade: WebSocket
    WebSocket-Origin: beta.XXXXX.com
    WebSocket-Location: ws://beta.XXXXX.com/chat/ws/

    Reply
  14. spacer Peter Bridge on said:

    This is really exciting stuff, and nice that Jetty has picked this up so fast, even if things are still moving around spec wise.
    So my interest is getting this to work with GWT. I have the above running fine, and all I’m doing extra is deploying my own Servlet to try and experiment with the websocket connection.
    In the above example you are using:
    var location = document.location.toString().replace(‘http:’,'ws:’);
    Which in my case is going to give me a GWT generated URL. That isn’t going to match against anything the server is expecting is my guess.
    Any tips on what my ws: url should look like? Or how to get some extra debug on the doWebSocketConnect call? so far I don’t think I’m hitting that method at all…
    WireShark seems to hint at some websocket attempt, but I only see the request side, but not an upgrade response.
    Somewhere better to discuss this?

    Reply
  15. spacer Greg Wilkins on said:

    Best to discuss this in the jetty-user@eclipse.org mailing list.
    You can hard code a ws URL just to get things going.

    Reply
  16. spacer Siva on said:

    Hi!
    I developed based on above example and deployed in jetty 7.0.2. When I browse the index.html, I gave a user name.After that Nothing is appear or still in the same snapshot. I guess web browser is not able to make web socket connection with server. Except using wireshark , I want to get the details (estblisehd HTTP connection/TCP connection)from the Jetty server. Is that possible?

    Reply
  17. spacer Siva on said:

    Hi!
    I do my self above experimentation. I couldnt get the expected out put. Once I get index.html page, I gave user name. In this time, server should do 101 action, but my case server gave 200 OK. Where is the problem?
    Anybody help me?

    Reply
  18. spacer Siva on said:

    Hi!
    I got success. I missed path direction in jetty server. Previous problem is solved.
    Now I compiled the src code of Web socket with test Web App. When I run I got this error. If you know, pls help me. Thanks in advance.
    Error is :
    2010-07-04 21:50:05.875:WARN::/test-jetty-webapp-7.0.2.v20100331/ws/
    java.lang.NullPointerException
    at org.eclipse.jetty.websocket.WebSocketFactory.upgrade(WebSocketFactory.java:92)
    at org.eclipse.jetty.websocket.WebSocketServlet.service(WebSocketServlet.java:60)

    Reply
  19. spacer Greg Wilkins on said:

    Siva,
    blog comments are probably not the best place to do technical support. I would suggest posting to the jetty mailing list.
    However, serveral websocket bugs have been fixed in recent releases, so I would suggest using 7.1.4
    regards

    Reply
  20. spacer whong on said:

    I tried this code. However, I always get the onMessage(byte frame, byte[] data, int offset, int length) called, instead of the one supposed to handle the String.
    Any idea?

    Reply
  21. spacer peter on said:

    it’s time to move from tomcat to jetty and look a little bit closer to websockets
    now all browsers (exp. IE) support websockets

    Reply
  22. spacer Fail to invoke websocket 'onopen' method on said:

    I’m using your WebSocket server and a simple WebSocket client also.
    In server console it shows ‘new connection’ has been established.
    But, I have failed to send message to the sever using WebSocket’s ‘send’ method.
    So far as I know, to establish a successful connection between
    server and client, WebSocket’s ‘onopen’ method should be invoked.
    But, it does not invoke that method at all.
    So, please help me about this matter.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

*

*

spacer
spacer

*

You may use these HTML tags and attributes: <a class="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>