Grizzly 2.3.3: SPDY Server Push

Starting with 2.3.3, Grizzly offers support for SPDY server push mechanism.

Quote:
SPDY enables a server to send multiple replies to a client for a
single request.  The rationale for this feature is that sometimes a
server knows that it will need to send multiple resources in response
to a single request.  Without server push features, the client must
first download the primary resource, then discover the secondary
resource(s), and request them.  Pushing of resources avoids
the round-trip delay…

For sure, one might ask “what if the client already has pushed resource
cached locally?” It is true, we probably should not push all the associated
resources blindly, for example we probably should not push a huge file
when we are not sure whether or not the client already has it, on other side it might
be a good idea to push small icon, javascript, css resources even if the client
has them already cached because additional round-trips
(especially for mobile networks) might be more time consuming than
receiving extra data.

Grizzly provides *PushResource* builder in order to construct the descriptor for the
resource we want to push. For example:

File imageFile = new File("imgs/1.png");

PushResource pushResource = PushResource.builder()
    .statusCode(HttpStatus.OK_200)
    .contentType("image/png")
    .source(
            Source.factory(spdyStream)
            .createFileSource(imageFile))
    .build();

spdyStream.addPushResource("https://thishost:7070/imgs/1.png", pushResource);

In the sample above we instruct SPDY stream to initiate server push, and send
image file represented by the File object.
Similarly it is possible to build *PushResource* based on Grizzly Buffer, byte[] or String.

It is also possible to customize *PushResource* status code, reason phrase and
headers like:

// Push redirect information, so the client will not need to make additional
// request to get this information from the server

PushResource pushResource = PushResource.builder()
    .statusCode(HttpStatus.MOVED_PERMANENTLY_301)
    .header(Header.Location, "https://anotherhost:7070/imgs/1.png")
    .source(
        Source.factory(spdyStream)
        .createStringSource("The resource has been moved"))
    .build();

spdyStream.addPushResource("https://thishost:7070/imgs/1.png", pushResource);

And finally to give you more idea how the complete code looks like, here is an
*HttpHandler* example:

public class SpdyPushHttpHandler extends HttpHandler {

    @Override
    public void service(Request request, Response response) throws Exception {

        // Get SpdyStream information
        final SpdyStream spdyStream =
                (SpdyStream) request.getAttribute(SpdyStream.SPDY_STREAM_ATTRIBUTE);

        // If spdyStream is null - it is not a SPDY based request
        if (spdyStream != null) {
            // Push the file resource (image)
            spdyStream.addPushResource(
                    "https://serverhost:serverport/imgs/1.png",
                    PushResource.builder()
                    .contentType("image/png")
                    .statusCode(HttpStatus.OK_200)
                    .source(Source.factory(spdyStream)
                        .createFileSource(imgFile))
                    .build());
        }

        // Send the main page here
        response.setContentType("text/html");

        final Writer w = response.getWriter();
        StringBuilder sb = new StringBuilder(128);
        sb.append("<html><head><title>SPDY Push Test</title></head><body>");

        // Here we have the image reference on the main page
        sb.append("<img alt="noimg" src="\"/imgs/1.png\"" />");

        sb.append("</body></html>");

        response.setContentLength(sb.length());
        w.write(sb.toString());
    }
}

The complete SPDY example including Server Push can be found here.

Advertisements
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s