20090315 Comet

Post on 11-May-2015

1.680 views 3 download

Tags:

description

presentation on writing comet applications using grizzly framework on GlassFish

Transcript of 20090315 Comet

1

Writing Comet Web Application using GlassFish

Jeanfrancois Arcand Sun Microsystems

1

2

Agenda • What is Comet (aka Ajax Push) • What is Grizzly Comet Framework • Demo screan cast • What is Atmosphere • Summary • More info

> Tutorials > Project Grizzly

3

What is Ajax Push, exactly? Bending the rules of HTTP.

4

Ajax Poll vs Ajax Push Bending the rules of HTTP. •  Poll:

> Send a request to the server every X seconds. > The response is “empty” if there is no update.

•  Long Poll: > Send a request to the server, wait for an event to happen, then send the

response. > The response is never empty. > HTTP specification satisfied: indistinguishable from “slow” server

•  Http Streaming: > Send a request, wait for events, stream multi-part/chunked response, and

then wait for the events. > The response is continually appended to.

5

Comet on GlassFish

6

Introduction to Grizzly Comet • Grizzly Comet is a framework that ship with

GlassFish v2 and v3, and can also be embedded into any application using the Grizzly Embed interface

• The Grizzly Comet Framework includes a set of components that can be used for building Comet based application: > Grizzly Comet, Continuation, Grizzlet, Messages Bus,

•  It also support the JSON based Bayeux Protocol (aka Comet)

7

Grizzly Comet Framework • The Framework contains the classes required to add

support for Comet in a Web Application • Main classes to interact with (details next):

> CometContext > CometHandler > NotificationHandler

8

Grizzly Comet Framework How it works

Push data

filters push

send

send

9

Grizzly Comet in 3 steps

• Suspend: >  addCometHandler(CometHandler)

• Push: >  notify(<? extends Object>) // All suspended responses >  notify(<? extends Object>, CometHandler) // Only one

• Write: Inside CometHandler.onEvent() >  PrintWriter.write(CometEvent.attachment());

•  Resume: >  resumeCometHandler(CometHandler)

10

CometContext

• A CometContext is a distribution mechanism for pushing messages that are delivered to multiple subscribers called CometHandler (a la JMS Queue/Topic).

• All http response registered to a CometContext automatically becomes suspended, waiting for an event (a push) to happens.

• A browser receives only those messages published after the client suspend its response via CometContext.

11

CometContext – 5 APIs to remember

•  addCometHandler: Suspend the current response, await for data to be transformed.

•  resumeCometHandler: Resume the current response, and re-enable the normal http keep-alive mechanism.

•  notify(..): Dispatch data to the suspended response. •  registerAsyncRead: Allow a suspended response to

read asynchronously bytes. e.g avoid blocking waiting for the client to send all the bytes.

•  registerAsyncWrite: Allow a suspended response to write asynchronously bytes.

12

Creating a CometContext

/** * Create a {@link CometContext} * @param id - The topic associated with the {@link CometContext} * @return {@link CometContext} */ private CometContext createCometContext(String id){ CometEngine cometEngine = CometEngine.getEngine(); CometContext ctx = cometEngine.register(id); ctx.setExpirationDelay(idleTimeBeforeForcingResume); return ctx; }

13

Suspending an Http Response

// Create a CometContext based on this session id. twitterContext = createCometContext(sessionId);

// Create and register a CometHandler. ReflectorCometHandler handler = new ReflectorCometHandler (true,startingMessage,endingMessage);

// Pass the ‘suspended’ PrintWriter that can be used to write response // back to the client handler.attach(response.getWriter()); twitterContext.addCometHandler(handler);

14

Resuming an Http Response

if (event.getType() != CometEvent.READ) { printWriter.println(event.attachment()); printWriter.flush();

// long polling will resume automatically after the first event, // streaming will kept the response suspended if (!useStreaming){ event.getCometContext().resumeCometHandler(this); } }

15

Sharing data between suspended responses

twitterContext.notify(BEGIN_SCRIPT_TAG + toJsonp("You are now following ", message) + END_SCRIPT_TAG, CometEvent.NOTIFY, ch);

CometHandler twitterHandler = (CometHandler)followerContext.getAttribute("twitterHandler"); followerContext.notify(BEGIN_SCRIPT_TAG + toJsonp(name, " is now following " + message) + END_SCRIPT_TAG, CometEvent.NOTIFY, twitterHandler);

// Notify other registered CometHandler. twitterContext.notify("<script id='comet_" + counter++ + "'>" + "window.parent." + callback + "(" + message + ");</script>");

16

Writing data to a suspended response

public void onEvent(CometEvent event) throws IOException { try { if (event.getType() != CometEvent.READ) { printWriter.println(event.attachment()); printWriter.flush();

if (!useStreaming){ event.getCometContext().resumeCometHandler(this); } } } catch (Throwable t) { throw new IOException(t.getMessage()); } }

17

CometHandler • The CometHandler is the master piece of a Grizzly

Comet based application. • A CometHandler contains the business logic of what

will be pushed back to the browser. • A CometHandler might be invoked by the Container:

> When the response is suspended or resumed > When a push operation happens > When a I/O operations are ready to be process

(asynchronous read or write) > When the browser close the connection.

18

CometHandler API

//Invoked when CometContext.notify() is called public void onEvent(CometEvent ce);

// Invoked when the browser close a suspended // connection or when the suspend timeout expire. public void onInterrupt(CometEvent ce); // Invoked when the request is suspended public void onInitialize(CometEvent ce);

// Invoked when the request is resumed public void onTerminate(CometEvent ce);

19

Example: ReflectorCometHandler /** * Write {@link CometEvent#attachment} and resume the connection if * {@link ReflectorCometHandler#useStreaming} is <tt>false</tt> * @param event * @throws java.io.IOException */ public void onEvent(CometEvent event) throws IOException { try { if (event.getType() != CometEvent.READ) { printWriter.println(event.attachment()); printWriter.flush();

if (!useStreaming){ event.getCometContext().resumeCometHandler(this); } } } catch (Throwable t) { throw new IOException(t.getMessage()); } }

20

NotificationHandler •  The NotificationHandler object is the life saver when writing Comet

application •  This is inside that object that you will decide to what to do with

the push operation: – Throttle: If too many push occurs simultaneously, should we delay

them? – Aggregate: Should we cache push operations and aggregate them to

avoid overloading the network? – Filter: Should all messages by pushed back to the client. – Should a thread pool be used to improve the push speed operation?

Should a JMS backed be used to deliver the message?

•  The DefaultNotificationHandler push all messages.

21

NotificationHandler – Main API

/** * Set to <tt>true</tt> if the invoker of notify() should block when * notifying Comet Handlers. */ public void setBlockingNotification(boolean blockingNotification);

/** * Notify all {@link CometHandler}. * @param cometEvent the CometEvent used to notify CometHandler * @param iteratorHandlers An iterator over a list of CometHandler */ public void notify(CometEvent cometEvent,Iterator<CometHandler> iteratorHandlers) throws IOException;

22

NotificationHandler - Filtering

public void notify(CometEvent<String> ce,List<CometHandler> l){

escape(ce);

discard(ce);

}

23

NotificationHandler - Clustering

@Override public void notify(CometEvent cometEvent, Iterator<CometHandler> iteratorHandlers) throws IOException { try { // Push to the cluster ObjectMessage message = jmsSession.createObjectMessage(cometEvent); messageproducer.send(message); // Push locally super.notify(cometEvent,iteratorHandlers); } catch (JMSException ex) { throw new IOException("comet JMS send failed ", ex); } }

24

Demo

25

How the client looks like? • The client open a single connection to the server

> Use http-streaming • The Flickr Letters are powered by the a jMaki library

which use http-streaming. • The Follower/Following updates are made using a

long poll connection, powered by the behavior.js framework.

26

How the client looks like? • The client open a single connection to the server

> Use http-streaming • The Flickr Letters are powered by the a jMaki library

which use http-streaming. • The Follower/Following updates are made using a

long poll connection, powered by the behavior.js and prototype.js framework.

27

What is Project Atmosphere

•  Since July 2006 the Grizzly Comet Framework and its extensions’ popularity keep increasing.

>  Among the most popular framework right now. •  Comet techniques aren't standardized among Web Container

>  Grizzly Comet applications aren't portable (cannot run on Tomcat nor Jetty) ‏•  Servlet 3.0 will supports only a subset of Comet

>  No async I/O, No pushing functionalities >  Way too complicated (this is my personal opinion ) >  Support will takes time (Spec to be finalized) ‏

The state of Comet (Ajax Push) right now

28

What is Project Atmosphere (con't)‏

• Atmosphere is a POJO based framework using Inversion of Control (IoC) to bring Comet to the masses.

• A framework which can run on any Java based Web Server.....without having to wait for Servlet 3.0 or without the needs to learn how Comet support has been differently implemented by current Web Server supporting Comet

• Run on top of Servlet 2.5 compliant Web Server

So...

29

What is Project Atmosphere (con't)‏

• Grizzlet is a POJO based approach for writing Comet application. > Grizzlet only runs on top of the Grizzly Comet

Framework right now > Grizzly community asked many times to have the

concept ported to other Web Server • Evolve the Grizzlet...and make it the core of Project

Atmosphere. • Currently at version 0.1, with support for GlassFish,

Tomcat and Jetty.

Extends and improve the Grizzlet concept....

30

Architecture Reuse experience and code...from Grizzly Comet to Jersey!

Tomcat Comet Grizzly Comet Jetty Comet Blocking WS

Atmosphere Servlet Runtime Engine

Jersey's Injection Provider, IoC Support, and more....

Grizzlet (Atmosphere POJO)‏

Atmosphere re-usable Components library

User defined Atmosphere Component

31

Example Easy of use of Jersey, power of Grizzly Comet @Grizzlet(Grizzlet.Scope.APPLICATION)‏

@Path("myGrizzlet")‏

public class MyGrizzlet{

@Suspend(6000)‏

@GET

@Push

public String onGet(){

return "Suspending the connection";

}

@POST

@Push

public String onPost(@Context HttpServletRequest req,

@Context HttpServletResponse res) throws IOException{

res.setStatus(200);

res.getWriter().println("OK, info pushed");

return req.getParameter("chatMessage");

}

32

Demo

33

Summary The Asynchronous Web Revolution is Now

•  The Asynchronous Web will revolutionize human interaction

•  Writing Comet application with GlassFish is easy!

34

For More Information http://twitter.com/project_grizzly •  Getting Started with Grizzly Comet Framework on GlassFish

>  http://weblogs.java.net/blog/jfarcand/archive/2008/11/writing_a_twitt.html >  http://weblogs.java.net/blog/jfarcand/archive/2008/04/the_hitchhikers.html >  http://weblogs.java.net/blog/jfarcand/archive/2006/10/writting_a_come.html

•  GlassFish’s Comet Official Documentation: >  http://docs.sun.com/app/docs/doc/820-4496/ggrgy

•  GlassFish: http://glassfish.dev.java.net •  Grizzly: http://grizzly.dev.java.net

35

What is Project Grizzly •  Suite of embeddable components, which include:  

>  Framework: A Framework for building network I/O applications   >  Http: A Framework for building HTTP based applications   >  Comet: A Framework for building AjaxPush/Comet applications   >  Cometd/Bayeux: The JSON based Bayeux protocol.   >  Servlet: A tiny Servlet Container with a programmatic API (not compliant)   >  HttpService OSGi implementation: OSGi enabled WebServer

•  Components only available for via GlassFish Enterprise (not OSS)   >  Cluster Comet: Grizzly Comet cluster enabled.

•  Who is using Grizzly: GlassFish v2, GlassFish v3 (JRuby, Grails, Admin, Servlet Container, V3 kernel build on top of it), Jetty, Jersey,

JXTA, Netbeans, RESTlet, JXTA, Phobos, OpenESB, Sailfin, Futjisu, Sun Shared Shell, 4Home, Convergence, Ericsson, Nortel, Eventgnosis…and many many more!