How to use SPDY with Jetty

SPDY is a new protocol proposed by Google as a new protocol for the web. SPDY is compatible with HTTP but tries to reduce web page loading by using compression, mulitplexing and prioritization.To be more precise, the goals for speedy are: (http://dev.chromium.org/spdy/spdy-whitepaper).The SPDY project defines and implements an application-layer protocol for the web which greatly reduces latency.

The high-level goals for SPDY are:

To target a 50% reduction in page load time. Our preliminary results have come close to this target (see below).

To minimize deployment complexity. SPDY uses TCP as the underlying transport layer, so requires no changes to existing networking infrastructure.

To avoid the need for any changes to content by website authors. The only changes required to support SPDY are in the client user agent and web server applications.

To bring together like-minded parties interested in exploring protocols as a way of solving the latency problem. We hope to develop this new protocol in partnership with the open-source community and industry specialists

Some specific technical goals are:

To allow many concurrent HTTP requests to run across a single TCP session.

To reduce the bandwidth currently used by HTTP by compressing headers and eliminating unnecessary headers.

To define a protocol that is easy to implement and server-efficient. We hope to reduce the complexity of HTTP by cutting down on edge cases and defining easily parsed message formats.

To make SSL the underlying transport protocol, for better security and compatibility with existing network infrastructure. Although SSL does introduce a latency penalty, we believe that the long-term future of the web depends on a secure network connection. In addition, the use of SSL is necessary to ensure that communication across existing proxies is not broken.

To enable the server to initiate communications with the client and push data to the client whenever possible.

Setup maven

In this article we won’t look too much into the technical implementation of this protocol, but we’ll show you how you can start using and experimenting with SPDY yourself. For this we’ll use Jetty that has a SPDY implementation available in it’s latest release (http://wiki.eclipse.org/Jetty/Feature/SPDY).

So let’s get started. For this example we’ll let Maven handle the dependencies. And we’ll use the following POM.

NTP TLS extension

With this POM the correct libraries are loaded, so we can start using the specific SPDY classes in Jetty. Before we can really use SPDY though, we also need to configure Java to use an extension to the TLS protocol: TLS Next Protocol Negotiation or NPN for short. The details of this extension can be found on a googles technote (http://technotes.googlecode.com/git/nextprotoneg.html), but in short it comes down to this problem. What if we want to use a different protocol than HTTP when we’re making a connection to a server via TLS. We don’t know whether the server supports this protocol, and, since SPDY is focussed on speed, we don’t want the added latency of making a round trip. Even though there are a couple of different solutions , most suffer from unpredictability, extra roundtrips or breaks existing proxies (see (http://www.ietf.org/proceedings/80/slides/tls-1.pdf for more info). The proposed solution by Google is use the TLS’s extension mechanism to determine the protocol to be used. This is called “Next Protocol Negotiation” or NPN for short. With this extension the following steps are taken during the TLS handshake:

Client shows support for this extension

Server responds with this support and includes a list of supported protocols

Client sends the protocol he wants to use, which doesn’t have to be one offerede by the server.

Wrap HTTP request in SPDY

Now you can start using SPDY from Jetty. Jetty has support for this feature in two different ways. You can use it to transparently convert from SPDY to HTTP and back again or you can use it to directly talk SPDY. Let’s create a simple server configuration that hosts some static content using a SPDY enabled connection. For this we’ll use the following Jetty configuration:

As you can see in thia listing we specify a SSL context. This is needed since SPDY works over TLS. When we run this configuration Jetty will start listening on port 8443 for SPDY connections. Not all browser yet support SPDY, I’ve tested this example using the latest chrome browser. If you browse to https://localhost:8443/dummy.html (a file I created to test with) you’ll see the content of this file, just like you requested it using HTTPS. So what is happening here? Let’s first look at the SPDY session view that Chrome provides to determine whether we’re really using SPDY. If you navigate to the following url: chrome://net-internals/#events&q=type:SPDY_SESSION%20is:active. You’ll see something like the following figure.

In this view you can see all the current SPDY sessions. If everything was configured correctly you can also see a SPDY session connected to localhost. An additional check to see if everything is working as intended it to enable debugging of the NPN extension. You can do this by adding the following line to the Java code you use to start up the server:

NextProtoNego.debug=true;

Use the SPDY protocol directly

Now that we’ve got the HTTP over SPDY working, let’s look at the other option Jetty provides that allows us to directly send and recieve SPDY messages. For this example we’ll just create a client that sends a message to the server every 5 seconds. The server sends responses to a connected client with the number of received messages every second. First we create the server code.

server: … Received the following client data: Data from the client 2 Received the following client data: Data from the client 3 Received the following client data: Data from the client 4 Received the following client data: Data from the client 5 …

The code itself should be easy to understand from the inline comments. The only thing to remember, when you want to sent more then one data message over a stream is to make sure the second parameter of the constructor to StringDataInfo is set to false. If set to true, the stream will be closed after the data has been sent.

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Join Us

With 1,043,221 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!