X

WebSocket and Java EE 7 - Getting Ready for JSR 356 (TOTD #181)



WebSocket is
developed as part of HTML 5 specification and provides a
bi-directional, full-duplex communication channel over a single TCP
socket. It provides dramatic improvement over the traditional
approaches of Polling, Long-Polling, and Streaming for two-way
communication. There is no latency from establishing new TCP
connections for each HTTP message.



There is a WebSocket API
and the href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">WebSocket
Protocol. The Protocol defines "handshake" and "framing". The
handshake defines how a normal HTTP connection can be upgraded to a
WebSocket connection. The framing defines wire format of the
message. The design philosophy is to keep the framing minimum to
avoid the overhead. Both text and binary data can be sent using the
API.



WebSocket may look like a competing technology to Server-Sent Events
(SSE), but they are not. Here are the key differences:

  1. WebSocket can send and receive data from a client. A typical
    example of WebSocket is a two-player game or a chat application.
    Server-Sent Events can only push data data to the client. A
    typical example of SSE is stock ticker or news feed. With SSE,
    XMLHttpRequest can be used to send data to the server.

  2. For server-only updates, WebSockets has an extra overhead and
    programming can be unecessarily complex. SSE provides a simple
    and easy-to-use model that is much better suited.
  3. SSEs are sent over traditional HTTP and so no modification is
    required on the server-side. WebSocket require servers that
    understand the protocol.
  4. SSE have several features that are missing from WebSocket such
    as automatic reconnection, event IDs, and the ability to send
    arbitrary events.

    1. The client automatically tries to reconnect if the
      connection is closed. The default wait before trying to
      reconnect is 3 seconds and can be configured by including
      "retry: XXXX\n" header where XXXX is the milliseconds to wait
      before trying to reconnect.

    2. Event stream can include a unique event identifier. This
      allows the server to determine which events need to be fired
      to each client in case the connection is dropped in between.
    3. The data can span multiple lines and can be of any text
      format as long as EventSource message handler can process it.


  5. WebSockets provide true real-time updates, SSE can be
    configured to provide close to real-time by setting appropriate
    timeouts.



OK, so all excited about WebSocket ? Want to convert your POJOs into
WebSockets endpoint ?



websocket-sdk and href="http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/">GlassFish
4.0 is here to help!



The complete source code shown in this project can be href="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/4b695f458af5ccf8fff4b1fd96eb1160/totd181_glassfish_websocket.zip">downloaded
here.



On the server-side, the WebSocket SDK converts a POJO into a
WebSocket endpoint using simple annotations. Here is how a WebSocket
endpoint will look like:


@WebSocket(path="/echo")
public class EchoBean {

@WebSocketMessage
public String echo(String message) {
return message + " (from your server)";
}
}


In this code

  1. "@WebSocket" is a class-level annotation that declares a POJO
    to accept WebSocket messages. The path at which the messages are
    accepted is specified in this annotation.
  2. "@WebSocketMessage" indicates the Java method that is invoked
    when the endpoint receives a message. This method implementation
    echoes the received message concatenated with an additional
    string.





The client-side HTML page looks like


<div style="text-align: center;">
<form action="">
<input onclick="send_echo()" value="Press me" type="button">
<input id="textID" name="message" value="Hello WebSocket!" type="text"><br>
</form>
</div>
<div id="output"></div>



WebSocket allows a full-duplex communication. So the client, a
browser in this case, can send a message to a server, a WebSocket
endpoint in this case. And the server can send a message to the
client at the same time. This is unlike HTTP which follows a
"request" followed by a "response". In this code, the "send_echo"
method in the JavaScript is invoked on the button click. There is
also a <div> placeholder to display the response from the
WebSocket endpoint.



The JavaScript looks like:


<script language="javascript" type="text/javascript">
var wsUri = "ws://localhost:8080/websockets/echo";
var websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };

function init() {
output = document.getElementById("output");
}

function send_echo() {
websocket.send(textID.value);
writeToScreen("SENT: " + textID.value);
}

function onOpen(evt) {
writeToScreen("CONNECTED");
}

function onMessage(evt) {
writeToScreen("RECEIVED: " + evt.data);
}

function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}

function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}

window.addEventListener("load", init, false);
</script>



In this code

  1. The URI to connect to on the server side is of the format



    ws://<HOST>:<PORT>/websockets/<PATH>



    "ws" is a new URI scheme introduced by the WebSocket protocol.
    <PATH> is the path on the endpoint where the WebSocket
    messages are accepted. In our case, it is



    ws://localhost:8080/websockets/echo



    WEBSOCKET_SDK-1
    will ensure that context root is included in the URI as well.

  2. WebSocket is created as a global object so that the connection
    is created only once. This object establishes a connection with
    the given host, port and the path at which the endpoint is
    listening.

  3. The WebSocket API
    defines several callbacks that can be registered on specific
    events. The "onopen", "onmessage", and "onerror" callbacks are
    registered in this case. The callbacks print a message on the
    browser indicating which one is called and additionally also
    prints the data sent/received.

  4. On the button click, the WebSocket object is used to transmit
    text data to the endpoint. Binary data can be sent as one blob
    or using buffering.



The HTTP request headers sent for the WebSocket call are:



GET ws://localhost:8080/websockets/echo HTTP/1.1
Origin: http://localhost:8080
Connection: Upgrade
Sec-WebSocket-Extensions: x-webkit-deflate-frame
Host: localhost:8080
Sec-WebSocket-Key: mDbnYkAUi0b5Rnal9/cMvQ==
Upgrade: websocket
Sec-WebSocket-Version: 13

And the response headers received are

Connection:Upgrade
Sec-WebSocket-Accept:q4nmgFl/lEtU2ocyKZ64dtQvx10=
Upgrade:websocket
(Challenge Response):00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

The headers are shown in Chrome as shown below:

src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/39bd03b375765107330112656f40e23b/totd180_websocket_handshake.png">

The complete source code shown in this project can be href="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/4b695f458af5ccf8fff4b1fd96eb1160/totd181_glassfish_websocket.zip">downloaded
here.

The builds from websocket-sdk
are integrated in GlassFish 4.0 builds. Would you like to live on
the bleeding edge ? Then follow the instructions below to check
out the workspace and install the latest SDK:


  1. Check out the source codeclass="Apple-converted-space">



    svn checkout
    https://svn.java.net/svn/websocket-sdk~source-code-repository
  2. Build and install the trunk in your local repository as:



    mvn install

  3. Copy
    "./bundles/websocket-osgi/target/websocket-osgi-0.3-SNAPSHOT.jar"
    to "glassfish3/glassfish/modules/websocket-osgi.jar" in your href="http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/latest-glassfish.zip">GlassFish
    4 latest promoted build. Notice, you need to overwrite the
    JAR file.



Anybody interested in building a cool application using WebSocket
and get it running on GlassFish ? :-)



This work will also feed into href="http://jcp.org/en/jsr/detail?id=356">JSR 356 - Java API for
WebSocket.



On a lighter side, there seems to be less agreement on the name.
Here are some of the options that are prevalent:
  • WebSocket (W3C API, the URL is href="http://www.w3.org/TR/websockets">www.w3.org/TR/websockets
    though)

  • Web Socket (HTML5 Demos - href="http://html5demos.com/web-socket">html5demos.com/web-socket)

  • Websocket (Jenkins Plugin - href="https://wiki.jenkins-ci.org/display/JENKINS/Websocket%2BPlugin">wiki.jenkins-ci.org/display/JENKINS/Websocket%2BPlugin)

  • WebSockets (Used by Mozilla - href="http://developer.mozilla.org/en/WebSockets">developer.mozilla.org/en/WebSockets,
    but use WebSocket as well)

  • Web sockets (HTML5 Working Group - href="http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html">www.whatwg.org/specs/web-apps/current-work/multipage/network.html)

  • Web Sockets (Chrome Blog - href="http://blog.chromium.org/2009/12/web-sockets-now-available-in-google.html">blog.chromium.org/2009/12/web-sockets-now-available-in-google.html)


I prefer "WebSocket" as that seems to be most common usage and used
by the W3C API as well. What do you use ?


Join the discussion

Comments ( 10 )
  • Philippe Marschall Wednesday, June 20, 2012

    That's not a very useful post. In the real world you won't be implementing a hello world application. You'll have to integrate with Spring/CDI/EJB/MDB/…. This post does nothing to explain "websocket beans" or their API. Are they EJBs? Are they CDI beans? What's their lifecycle? How can they reference and be referenced by other beans? Is streaming supported? Can they be used without component scanning (which is slow)?

    I wouldn't have said anything if there was at least a work in progress spec that could be downloaded.


  • codeslinger compsalot Wednesday, June 20, 2012

    very interesting stuff.

    First question, what about security? What is to prevent millions of browsers from being turned into zombie spambots?

    Next question, What about server load? as I am sure you are well aware, servers are limited in the number of simultaneous connections they can maintain. If every web session started keeping a connection open, that would probably reduce effective server capacity by a factor of a hundred to a thousand.

    What about browser compatibility? I see Mozilla on that list, no surprise there, Mozilla is always at the leading edge of innovation, but what about sleepy giant Microsoft? have they expressed an intent to get on-board with this? they just recently finally got around to deciding to support SVG. What about Mac, or Opera? If the cross-browser support isn't there, this just becomes yet another major compatibility headache for developers. Or are you saying that your library will make this work with any browser that supports Java?

    What about performance? The Java Media Player was very cool, but unfortunately was way too slow to be usable, thus it's adoption has been near to zero. Is this going to be another one of those... brilliant but failed attempts? JavaScript itself is quite slow too.

    With regard to the name, WebSocket is singular; is only one connection per web page allowed? If you can have multiple connections then wouldn't it make more sense for the name to be plural? On second thought, we are actually talking about two different names... There is the name of the function itself which ought to be singular because it is creating a single connection per invocation, but then there is the name that is used when referring to the API in general, which it seems to me ought to be plural as long as more than one connection is possible within a web page. Just my two cents...

    Have a great day!


  • Muthuselvam Sunday, June 24, 2012

    This is very interesting article. Thanks a lot for posting..


  • guest Thursday, August 9, 2012

    I like the simplicity of the development model using anotation.

    But I have a question :

    Can we use a @WebsocketMessage method of a Websocket endpoint in a MDB to publish JMS messages to client browsers?

    "codeslinger compsalot", if you need information on Websocket support see the stackoverflow article http://stackoverflow.com/questions/1253683/what-browsers-support-html5-websocket-api/2700609#2700609. I think it's a pretty complete and up to date article.


  • guest Friday, January 25, 2013

    Is there any change in the Java class as per the newest spec (say build 70). Somehow I get the following in the error console.

    --

    [12:43:34.460] Firefox can't establish a connection to the server at ws://localhost:8080/websockets/echo


  • Neil Friday, January 25, 2013

    The specifications has been changed a bit after this sample was posted

    Now the class level annotation is

    @WebSocketEndpoint(value="/echo",factory = Whiteboard.DummyEndpointFactory.class)

    Also the imports have become

    import javax.websocket.EndpointFactory;

    import javax.websocket.WebSocketEndpoint;

    import javax.websocket.WebSocketMessage;

    However I still get the error

    Timestamp: 1/25/2013 1:39:15 PM

    Error: The connection to ws://localhost:8080/websockets/echo interrupted while the page was loading.

    Source File: http://localhost:8080/websockets/

    Line: 15


  • Neil Friday, January 25, 2013

    problem solved ! It works

    but ehe interrupted error happens when the page is refreshed , but it continues to transmit messages


  • christi parks Wednesday, January 30, 2013

    Hello, sir i would like to ask that what is the scope of java training, what all topics should be covered and it is kinda bothering me … and has anyone studies from this course http://www.wiziq.com/course/1779-core-and-advance-java-concepts of core and advance java online ?? or tell me any other guidance...

    would really appreciate help… and Also i would like to thank for all the information you are providing on java concepts.


  • Arun Gupta Wednesday, January 30, 2013

    Oracle offers lots of training courses and they are explained at:

    http://education.oracle.com/pls/web_prod-plq-dad/ou_product_category.getFamilyPage?p_family_id=48

    Are you looking for help in anything specific ?


  • Archimedes Trajano Thursday, June 20, 2013

    The API has changed a bit. I have actually documented how to do this with Maven and Angular http://www.trajano.net/2013/06/java-ee-7-web-sockets-with-angularjs/


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha