{"id":12,"date":"2011-06-25T16:47:01","date_gmt":"2011-06-25T16:47:01","guid":{"rendered":"http:\/\/blog.johannes-beck.name\/?p=12"},"modified":"2011-06-25T19:16:25","modified_gmt":"2011-06-25T17:16:25","slug":"websockets","status":"publish","type":"post","link":"https:\/\/blog.johannes-beck.name\/?p=12","title":{"rendered":"Web Sockets"},"content":{"rendered":"<p><em>Today we look into Websockets and provide two small code examples.<\/em><\/p>\n<h2>What are Websockets?<\/h2>\n<p>In short summary you can paraphrase the key notions of WebSockets like this:<\/p>\n<ul>\n<li>WebSockets is a technique for two-way communication over one TCP socket.<\/li>\n<li>It is designed to be implemented in web browsers and web servers.<\/li>\n<li>It is an extra part of the coming HTML5 standard.<\/li>\n<li>It is a generalized kind of AJAX, including a PUSH technology for the web.<\/li>\n<li>It reduces unnecessary network traffic and latency compared to polling requests.<\/li>\n<\/ul>\n<p>Websockets consists of two major parts:<\/p>\n<ul>\n<li>The <a href=\"http:\/\/dev.w3.org\/html5\/websockets\/\">WebSocket (Javascript Client) API<\/a> is being standardized by the W3C<\/li>\n<li>The <a href=\"http:\/\/tools.ietf.org\/html\/draft-ietf-hybi-thewebsocketprotocol-07\">WebSocket protocol<\/a> is being standardized by the IETF.<\/li>\n<\/ul>\n<h2>The WebSockets Protocol<\/h2>\n<p>To establish a WebSocket connection, the client sends a WebSocket handshake request, and the server sends a WebSocket handshake response.<br \/>\nThe handshake is done via the HTTP upgrade mechanism to upgrade to the WebSocket protocol.<\/p>\n<p>Client request:<\/p>\n<pre>\tGET \/ws HTTP\/1.1\r\n\t\u2026\r\n\tUpgrade: websocket<\/pre>\n<p>Server response:<\/p>\n<pre>\tHTTP\/1.1 101 Switching Protocols\r\n\tUpgrade: websocket\r\n\tConnection: Upgrade\r\n\tSec-WebSocket-Accept: \u2026<\/pre>\n<p>By using standard HTTP for the handshake, the websockets traverse firewalls and proxies.<br \/>\nWhat is special about the websockets protocol is that it allows the client to connect to arbitrary endpoints and is not bound to \u201esame location as original request\u201c policy.<br \/>\nThe protocol and endpoint are notated with ws:\/\/hostname:port\/uri or wss:\/\/hostname:port\/uri for the encrypted version of the protocol.<\/p>\n<p>Another remarkable fact is that there is no header data in protocol,. The payload is delimited with 1 start and 1 end byte,<br \/>\nso that the protocol overhead is exactly 2 bytes per message.<br \/>\nStandard HTTP request usually have something between 500 to 1000 bytes in header data.<\/p>\n<h2>The Websocket API<\/h2>\n<p>The Websocket API is a really small Javascript API, which allows the client to send and receice data over the websocket protocol.<br \/>\nThe complete API can be listed within a single interface, which consists in a constructor, 4 event handlers and 2 methods.<\/p>\n<pre>\t[Constructor(in DOMString url, optional in DOMString protocol)]\r\n\tinterface WebSocket {\r\n\t\treadonly attribute DOMString URL;\r\n\t\tconst unsigned short CONNECTING = 0;\r\n\t\tconst unsigned short OPEN = 1;\r\n\t\tconst unsigned short CLOSED = 2;\r\n\r\n\t\treadonly attribute unsigned short readyState;\r\n\t\treadonly attribute unsigned long bufferedAmount;       \r\n\r\n\t\tattribute Function onopen;\r\n\t\tattribute Function onmessage;\r\n\t\tattribute Function onclose;\r\n\t\tattribute Function onerror;\r\n\r\n\t\tboolean send(in DOMString data);\r\n\t\tvoid close();\r\n\t}<\/pre>\n<p>And here is how you use the API:<\/p>\n<ol>\n<li><strong>Start handshake<\/strong>:\n<pre>\t\tvar myWebSocket = new WebSocket(\"ws:\/\/www.websockets.org\");<\/pre>\n<\/li>\n<li><strong>Define event handlers<\/strong>:\n<pre>\t\tmyWebSocket.onopen=function(evt) {\r\n                  alert(\"Connection open ...\"); };\r\n\t\tmyWebSocket.onmessage=function(evt) {\r\n                  alert( \"Received Message: \"  +  evt.data); };\r\n\t\tmyWebSocket.onclose=function(evt) {\r\n                  alert(\"Connection closed.\"); };<\/pre>\n<\/li>\n<li><strong>Call the methods<\/strong>:\n<pre>\t\tmyWebSocket.send(\"Hello Web Sockets!\");\r\n\t\tmyWebSocket.close();<\/pre>\n<\/li>\n<\/ol>\n<p>What you need is a web browser which implements the Websocket API.<br \/>\nSince the standard is not yet finished, the implementations are ongoing process.<br \/>\nCurrently Google Chrome 9, Apple Safari 5 and iOs Safari 4.2 implement it.<br \/>\nFirefox 4, Opera 11 and Opera Mobile 11 have also implemented it, bit disabled it by default.<br \/>\nAnd the IE 9 needs a extra plugin to support Websockets.<\/p>\n<p>On the server side their are various implementation for the websocket protocol.<br \/>\nFor Java you can use Glassfish 3.1, Jetty 7, Resin 4.0.2, <a href=\"http:\/\/jwebsocket.org\">jWebsocket<\/a>.<br \/>\nAll have their own APIs, since the websocket protocol is currently not part of Servlet Specification, but this may be added in JEE7.<br \/>\nFor PHP there is phpwebsockets, for Python mod_pywebsocket, for Ruby web-socket-ruby and if you are doing<br \/>\nserver-side JavaScript there is a plugin for node.js.<\/p>\n<h2>Example code: Hello Websockets<\/h2>\n<p>After all the explanation I want to go into two small examples. Let&#8217;s start with the &#8220;Hello World&#8221; of WebSockets.<br \/>\nWe will do a Echo-Server, where the client will send some message over the wire and the server will send back the message.<br \/>\nFor the server side I&#8217;ve chosen to use Jetty (since I&#8217;m a Java guy most of the time), and using Maven for the infrastructure.<br \/>\nSo let&#8217;s have a look at the POM definition, after we created the project with the usual<br \/>\n<a href=\"http:\/\/maven.apache.org\/guides\/mini\/guide-webapp.html\">archetype for a web application<\/a>:<\/p>\n<pre>&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\r\n    xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n    xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0\r\n    http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n  ... \/\/ the usual stuff\r\n  &lt;packaging&gt;war&lt;\/packaging&gt;\r\n  &lt;properties&gt;\r\n    &lt;jetty.version&gt;7.3.0.v20110203&lt;\/jetty.version&gt;\r\n  &lt;\/properties&gt;\r\n  &lt;build&gt;\r\n    &lt;plugins&gt;\r\n\t...\r\n      &lt;plugin&gt;\r\n        &lt;groupId&gt;org.mortbay.jetty&lt;\/groupId&gt;\r\n        &lt;artifactId&gt;jetty-maven-plugin&lt;\/artifactId&gt;\r\n        &lt;version&gt;${jetty.version}&lt;\/version&gt;\r\n        &lt;configuration&gt;\r\n          &lt;scanIntervalSeconds&gt;10&lt;\/scanIntervalSeconds&gt;\r\n          &lt;webAppConfig&gt;\r\n            &lt;contextPath&gt;\/websockets&lt;\/contextPath&gt;\r\n            &lt;descriptor&gt;${basedir}\/src\/main\/webapp\/web.xml&lt;\/descriptor&gt;\r\n          &lt;\/webAppConfig&gt;\r\n        &lt;\/configuration&gt;\r\n      &lt;\/plugin&gt;\r\n    &lt;\/plugins&gt;\r\n  &lt;\/build&gt;\r\n  &lt;dependencies&gt;\r\n    &lt;dependency&gt;\r\n      &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt;\r\n      &lt;artifactId&gt;jetty-server&lt;\/artifactId&gt;\r\n      &lt;version&gt;${jetty.version}&lt;\/version&gt;\r\n    &lt;\/dependency&gt;\r\n    &lt;dependency&gt;\r\n      &lt;groupId&gt;org.eclipse.jetty&lt;\/groupId&gt;\r\n      &lt;artifactId&gt;jetty-websocket&lt;\/artifactId&gt;\r\n      &lt;version&gt;${jetty.version}&lt;\/version&gt;\r\n    &lt;\/dependency&gt;\r\n  &lt;\/dependencies&gt;\r\n&lt;\/project&gt;<\/pre>\n<p>If you look at it you&#8217;ll see that we&#8217;re using the Jetty Server as compile time dependency (for the Websocket API) and the runtime container.<br \/>\nThat is the only thing we actually need, and so we can start coding the server side.<br \/>\nFor the Jetty implementation of Websockets that means we have to implement a servlet, which inherits from the<br \/>\n<code>org.eclipse.jetty.websocket.WebSocketServlet<\/code>.<\/p>\n<p><code> <\/code><\/p>\n<pre><code>\tpackage echo;\r\n\r\n\timport java.io.IOException;\r\n\timport javax.servlet.http.HttpServletRequest;\r\n\timport org.eclipse.jetty.websocket.WebSocket;\r\n\timport org.eclipse.jetty.websocket.WebSocketServlet;\r\n\r\n\tpublic class EchoServlet extends WebSocketServlet {\r\n\r\n\t  protected WebSocket doWebSocketConnect(HttpServletRequest req,\r\n             String resp) {\r\n\t\treturn new EchoWebSocket();\r\n\t  }\r\n\r\n\t  private class EchoWebSocket implements WebSocket {\r\n\t\tprivate Outbound outbound;\r\n\r\n\t\tpublic void onConnect(Outbound outbound) {\r\n\t\t  this.outbound = outbound;\r\n\t\t}\r\n\r\n\t\tpublic void onDisconnect() {\r\n\t\t  this.outbound = null;\r\n\t\t}\r\n\r\n\t\tpublic void onMessage(final byte frame, String data) {\r\n\t\t  try {\r\n\t\t\tSystem.out.println(\"Received: \" + data);\r\n\t\t\toutbound.sendMessage(\"You said: \" + data);\r\n\t\t  } catch (IOException e) {\r\n\t\t\te.printStackTrace();\r\n\t\t  }\r\n\t\t}\r\n\r\n\t\tpublic void onMessage(byte arg0, byte[] arg1, int arg2, \r\n                  int arg3) {\r\n\t\t}\r\n\r\n\t\tpublic void onFragment(boolean arg0, byte arg1, byte[] arg2,\u00a0\r\n                  int arg3, int arg4) {\r\n\t\t}\r\n\t  }\r\n\t}\r\n\t<\/code><\/pre>\n<p><code> <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>What the servlet does is easy to see. When the handshake starts the <code>doWebSocketConnect<\/code> is called and we create our own Websocket.<br \/>\nThis is the <code>EchoWebSocket<\/code> which has to implement the <code>org.eclipse.jetty.websocket.WebSocket<\/code> interface.<br \/>\nWhen the connection is established an <code>Outbound<\/code> is created, since we want to send the incoming message back to client.<br \/>\nAnd when a message arrives, the <code>onMessage<\/code> method is called, and we send the message back over the <code>Outbound<\/code>.<br \/>\nThe other two message methods can have an empty implementation since we don&#8217;t intend to send binary data.<br \/>\nFor the server to be complete we just have to register the Servlet in the <code>web.xml<\/code>.<\/p>\n<p>What we need now is the client side. For that we code a JSP page, which delivers a small HTML page:<\/p>\n<p><code> <\/code><\/p>\n<pre><code>&lt;!DOCTYPE html&gt;\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;title&gt;My first WebSocket app!&lt;\/title&gt;\r\n&lt;script type=\"text\/javascript\"&gt;\r\n\tvar ws = new WebSocket(\"ws:\/\/localhost:8080\/websockets\/echo\");\r\n\tws.onopen = function(ev) {\r\n\t\twindow.alert(\"connection is up\");\r\n\t};\r\n\tws.onmessage = function(ev) {\r\n\t\tdocument.getElementById(\"receive\").innerHTML = ev.data;\r\n\t};\r\n\tfunction send() {\r\n\t\tws.send(document.getElementById(\"send\").value);\r\n\t}\r\n&lt;\/script&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n  &lt;h2&gt;Websocket Hello World&lt;\/h2&gt;\r\n  &lt;input type=\"text\" id=\"send\" size=\"40\" \/&gt; \r\n  &lt;input type=\"button\" value=\"send\" onclick=\"send()\"\/&gt;\r\n  &lt;hr\/&gt;\r\n  &lt;p id=\"receive\"\/&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n\t<\/code><\/pre>\n<p><code> <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>There&#8217;s not much magic in there either. The page has a text input for the message to be sent and a paragraph section for the answer that we receive.<br \/>\nWhen the page is loaded the WebSocket is created.<br \/>\nWhen you click on the button the input message is send, and when a message comes in, the payload is put into the paragraph.<\/p>\n<p>Now we got all pieces together, and with <code>mvn jetty:run<\/code> we can start the servlet engine and point our browser<br \/>\nto <a href=\"http:\/\/localhost:8080\/websockets\/echo.jsp\">http:\/\/localhost:8080\/websockets\/echo.jsp<\/a>.<\/p>\n<h2>What to do with Websockets?<\/h2>\n<p>There are really huge fields to which you can apply websockets.<br \/>\nThink about all applications which have &#8220;real-time&#8221; communication patterns like chat server, twitter clients, collaboration, messaging, push email, news ticker or stock brokers<\/p>\n<p>And you are not limited to raw data or simple string being send over the wire.<br \/>\nThe next level yould be to send formatted data (as in XML or JSON), but you can also implement<br \/>\nhigh-level protocols messaging protocols on the client side (like JMS, Jabber or AMQP).<br \/>\nAnd since you are no longer bound to the same origin policy as in AJAX requests, you can<br \/>\nreplace and out-scale traditional AJAX requests: lower latencies by pushing data,<br \/>\nsave resources on the server side by avoiding long polling requests and a lower protocol overhead.<\/p>\n<h2>A more complex example: pushing server monitoring data<\/h2>\n<p>Now let&#8217;s get to a more complex example. We want to push server monitoring data (like the memory our VM uses) to a listening client.<br \/>\nSampling monitoring data can be done with JMX, using the <code>java.lang.management.ManagementFactory.<\/code>.<br \/>\nCalling <code>ManagementFactory.getMemoryMXBean()<\/code> delivers the <code>java.lang.management.MemoryMXBean<\/code>,<br \/>\nwhich we can ask about the status of the VM&#8217;s memory:<\/p>\n<pre><code>\r\n\t\tMemoryMXBean.getHeapMemoryUsage().getInit());\r\n\t\tMemoryMXBean.getHeapMemoryUsage().getCommitted());\r\n\t\tMemoryMXBean.getHeapMemoryUsage().getUsed());\r\n\t\tMemoryMXBean.getHeapMemoryUsage().getMax());\r\n\t\tMemoryMXBean.getNonHeapMemoryUsage().getInit());\r\n\t\tMemoryMXBean.getNonHeapMemoryUsage().getCommitted());\r\n\t\tMemoryMXBean.getNonHeapMemoryUsage().getUsed());\r\n\t\tMemoryMXBean.getNonHeapMemoryUsage().getMax());\r\n\t\tMemoryMXBean.getObjectPendingFinalizationCount());\r\n\t<\/code><\/pre>\n<p><code> <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>So what we do is quite straight forward. We create a plain Java Bean <code>MemoryUsage<\/code> which can hold all this data, and we create a timer task<br \/>\nwhich reads the data from the MemoryMXBean on a regular basis and creates a MemoryUsage object.<\/p>\n<p><code> <\/code><\/p>\n<pre><code>\r\n\tpublic class MemoryUsage {\r\n\t\tprivate long heapMemoryUsageInit;\r\n\t\tprivate long heapMemoryUsageUsed;\r\n\t\tprivate long heapMemoryUsageCommitted;\r\n\t\tprivate long heapMemoryUsageMax;\r\n\t\tprivate long nonHeapMemoryUsageInit;\r\n\t\tprivate long nonHeapMemoryUsageUsed;\r\n\t\tprivate long nonHeapMemoryUsageCommitted;\r\n\t\tprivate long nonHeapMemoryUsageMax;\r\n\t\tprivate int objectPendingFinalizationCount;\r\n\t\tprivate long timestamp;\r\n\r\n\t\t\/\/ add getters and setters\r\n\t}\r\n\r\n\tpublic class MonitoringSocket implements WebSocket {\r\n\t\t\/\/ similar to the echo websocket\r\n\r\n\t\tprivate java.util.Timer timer;\r\n\r\n\t\tpublic void onConnect(Outbound outbound) {\r\n\t\t\tthis.outbound = outbound;\r\n\t\t\ttimer = new Timer();\r\n\t\t\ttimer.schedule(new java.util.TimerTask() {\r\n\t\t\t\tpublic void run() {\r\n\t\t\t\t\toutbound.sendMessage(frame, \r\n                                                 stringify(getData()));\r\n\t\t\t\t}, new java.util.Date(), 2000);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tpublic void onDisconnect() {\r\n\t\t\ttimer.cancel();\r\n\t\t}\r\n\t}\r\n\t<\/code><\/pre>\n<p><code> <\/code><\/p>\n<p>&nbsp;<\/p>\n<p>We create a websocket servlet and a WebSocket instance like we did in the Echo example.<br \/>\nWhat we add is a <code>TimerTask<\/code> we start when a connection is created.<br \/>\nThis task is tunning every 2 seconds and will get the monitoring data and make a text message out of the<br \/>\nMemoryUsage object. What is now still missing are the <code>getData()<\/code> and the <code>stringify()<\/code><br \/>\nmethods. The first one is a simple one, just create the Java Bean and set its values from JMX:<\/p>\n<p><code> <\/code><\/p>\n<pre><code>\r\n  public MemoryUsage getData() {\r\n    MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();\r\n    MemoryUsage memoryUsage = new MemoryUsage();\r\n    memoryUsage.setHeapMemoryUsageInit(\r\n      memoryMXBean.getHeapMemoryUsage().getInit());\r\n    memoryUsage.setHeapMemoryUsageCommitted(\r\n      memoryMXBean.getHeapMemoryUsage().getCommitted());\r\n    memoryUsage.setHeapMemoryUsageUsed(\r\n      memoryMXBean.getHeapMemoryUsage().getUsed());\r\n    memoryUsage.setHeapMemoryUsageMax(\r\n      memoryMXBean.getHeapMemoryUsage().getMax());\r\n    memoryUsage.setNonHeapMemoryUsageInit(\r\n      memoryMXBean.getNonHeapMemoryUsage().getInit());\r\n    memoryUsage.setNonHeapMemoryUsageCommitted(\r\n      memoryMXBean.getNonHeapMemoryUsage().getCommitted());\r\n    memoryUsage.setNonHeapMemoryUsageUsed(\r\n      memoryMXBean.getNonHeapMemoryUsage().getUsed());\r\n    memoryUsage.setNonHeapMemoryUsageMax(\r\n      memoryMXBean.getNonHeapMemoryUsage().getMax());\r\n    memoryUsage.setObjectPendingFinalizationCount(\r\n      memoryMXBean.getObjectPendingFinalizationCount());\r\n    memoryUsage.setTimestamp(System.currentTimeMillis());\r\n    return memoryUsage;\r\n}\r\n<\/code><\/pre>\n<p>And how you want to deliver the data to the client is left as an execise to the reader, there may be different ways you might want to go:<\/p>\n<ul>\n<li>Make a larger text string where you format the name and the value. The client can paste the message in a text box as we did in the echo example.<\/li>\n<li>Write a method which makes a HTML snippet out of the values, or format the data to XML<\/li>\n<li>Use a bean serialization engine and deliver XML or JSON to the client. In my code I have used<br \/>\nthe <a href=\"http:\/\/jackson.codehaus.org\/\">Jackson JSON Processor<\/a>.<\/li>\n<\/ul>\n<p>On the client side we use the approach as before, using JSP to deliver HTML pages and JavaScript.<br \/>\nSince I have decided to deliver JSON arrays to the client, the message handler in JavaScript takes the<br \/>\nJSON data and puts them into HTML table cells. This is pretty straight-forward code, so if you want to have look at it<br \/>\ntake a look at the sources.<\/p>\n<h2>From here on&#8230;<\/h2>\n<p><a href=\"\/wp-content\/uploads\/2011\/06\/monitoring-websockets.zip\">Download<\/a> the source code &#8211; with some more gimmicks &#8211; from the examples I&#8217;ve shown.<\/p>\n<p>If you want dig deeper into the matter you can visit <a href=\"http:\/\/websocket.org\/\">http:\/\/websocket.org<\/a> for more<br \/>\ninformation, or go to the standards body and have a look at the<br \/>\n<a href=\"http:\/\/dev.w3.org\/html5\/websockets\/\">WebSocket API<\/a> and<br \/>\nthe <a href=\"http:\/\/tools.ietf.org\/html\/draft-ietf-hybi-thewebsocketprotocol-07\">WebSocket protocol<\/a> definitions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we look into Websockets and provide two small code examples. What are Websockets? In short summary you can paraphrase the key notions of WebSockets like this: WebSockets is a technique for two-way communication over one TCP socket. It is designed to be implemented in web browsers and web servers. It is an extra part [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[5,61,7,8,6],"class_list":["post-12","post","type-post","status-publish","format-standard","hentry","category-software-development","tag-html5","tag-java","tag-jetty","tag-maven","tag-websockets"],"_links":{"self":[{"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/posts\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12"}],"version-history":[{"count":11,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":25,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=\/wp\/v2\/posts\/12\/revisions\/25"}],"wp:attachment":[{"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.johannes-beck.name\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}