Contents

Getting Started With WebSockets

The WebSockets protocol and API is an emerging standard that seeks to provide high-quality, bidirectional communication between a browser (or other web client) and a server. The goal is to eventually replace Comet techniques like long polling. Jetty has supported the various WebSocket drafts in the 7.x and 8.x releases.

You don’t want to do this!

This document shows you how to use WebSockets from the lowest levels; it targets framework developers who want to use WebSockets, and application developers who can't stand not knowing what is under the hood. However, we would not advise that any application programmer should follow these examples to build an application. WebSockets is not a silver bullet, and on it’s own will never be simple to use for nontrivial applications (see Is WebSocket Chat Simpler?). We recommend that you look toward frameworks like Cometd, that private a higher level of abstraction, hide the technicalities, and allow you to use either Comet long polling or WebSockets transparently.

Test Client and Server

The simplest way to get started is to download a Jetty aggregate Jar that comes complete with a test WebSocket client and server. You can do this using a browser or with the following command line wgets:

The output from the test client is similar to ping. You can use the options you discover by using –help to try out different types of tests, including fragmentation and aggregation of WebSocket frames.

Using a Browser

Using a Java client is not much use unless you want to write a desktop application that uses WebSocket (a viable use). But most users of WebSocket want to use the browser as a client. So point your browser at the TestServer at http://localhost:8080.

The WebSocket TestServer also runs an HTTP file server at the directory given by –docroot, so in this case you should see in the browser a listing of the directory in which you ran the test server.

To turn the browser into a WebSocket client, you need to serve some HTML and Javascript that executes in the browser and talks back to the server using Websockets.

Create the file index.html in the same directory you ran the server from.

Put into it the following contents which you can download from here. This index file contains the HTML, CSS and Javascript for a basic chat room.

You should now be able to point your browser(s) at the test server, see a chat room, and join it. If your browser does not support WebSockets, you’ll receive a warning.

Understanding How the Client Works

The initial HTML view has a prompt for a user name. When a you enter a name, the system calls the join method, which creates the WebSocket to the server. The URI for the WebSocket derives from the document's location. Call back functions are registered for open, message and close events. The org.ietf.websocket.test-echo-broadcast subprotocol is specified as this echoes all received messages to all other broadcast connections, providing the semantic a chat room requires:

When the WebSocket successfully connects to the server, it calls the onopen callback, which changes the appearance of the chat room to prompt for a chat message. It also sends a message saying the user has joined the room:

When the browser receives a WebSocket message over the connection, the system calls the onmessage callback with a message object. The Jetty implementation looks for the username and colon, strips out any markup, and then appends the message to the chat room:

Understanding How the Server Works

The server side code for this chat room uses an embedded Jetty server and is written against the Jetty WebSocket APIs that are not part of the WebSocket standard. There is not yet even a proposed standard for serverside WebSocket APIs, but it is a topic for consideration with the servlet 3.1 JSR.

The resource handler is responsible for serving the static content like HTML and javascript. The WebSocketHandler looks for WebSocket handshake request and handles them by calling the doWebSocketConnect method, which we have extended to create a WebSocket depending on the sub protocol passed:

Below is a simplification of the test WebSocket from the test server, that excludes the shared code for the other protocols supported. Like the javascript API, there is an onOpen,onClose and onMessage callback. The onOpen callback is passed in a Connection instance that is used to send messages. The implementation of onOpen adds the websocket to a collection of all known websockets, and onClose is used to remove the websocket. The implementation of onMessage is to simply iterate through that collection and to send the received message to each websocket:

Don’t do it this way!

Now you know the basics of how websockets works, I repeat my warning that you should not do it this way – unless you are a framework developer. Even then, you are probably going to want to use the WebSocketServlet and a non embedded jetty, but the basic concepts are the same. Note the strength of the jetty solution is that it terminates both WebSocket connections and HTTP requests in the same environment, so that mixed frameworks and applications are easy to create.

Application developers should really look to a framework like cometd rather than directly coding to websockets themselves. It is not that the mechanics of websockets are hard, just that they don’t solve all of the problems that you will encounter in a real world comet application.