atmosphere whitepaper

33
Atmosphere Framework ‐ White Paper 1 Atmosphere Framework White Paper Jeanfrancois Arcand ([email protected]) Version 0.6

Upload: pablo-iturralde

Post on 24-Mar-2015

185 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 1

AtmosphereFramework

WhitePaper

JeanfrancoisArcand([email protected])

Version0.6

Page 2: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 2

Introduction ................................................................................................................................................. 4

Terminology................................................................................................................................................. 4

Note.................................................................................................................................................................. 4

WhatistheAtmosphereFramework?.............................................................................................. 5

Gettingstarted ............................................................................................................................................ 6

AtmosphereMainConcept .................................................................................................................... 8

Chapter1:AtmosphereJersey(AsynchronousRESTfulwebApplication) ...................... 9

TheConcepts........................................................................................................................................... 9

@Suspend.............................................................................................................................................. 10

@Resume............................................................................................................................................... 11

@Broadcast .......................................................................................................................................... 11

InjectableObjects............................................................................................................................... 14

WritingasimpleChatapplicationusingAtmosphereJersey ......................................... 14

Chapter2:AtmosphereRuntime(CometPortableRuntime) ............................................. 16

Theconcepts ........................................................................................................................................ 16

AtmosphereResource....................................................................................................................... 16

AtmosphereResourceEvent........................................................................................................... 17

ReadytouseAtmosphereHandler.............................................................................................. 17

WritingasimpleChatapplicationusingAtmosphereruntime ..................................... 19

Chapter3:AtmosphereMeteor ........................................................................................................ 25

TheConcepts........................................................................................................................................ 25

WritingasimpleChatapplicationusingAtmosphereMeteor ....................................... 26

Chapter4:AtmospherePlugIn......................................................................................................... 28

AtmosphereGrizzlyPlugIn........................................................................................................... 28

UseProjectGrizzlyWebFrameworktoembedAtmosphere .................................... 28

DeployingyourAtmosphereAdapterusingGlassFish .................................................. 28

AtmosphereClusterPlugIn .......................................................................................................... 29

Page 3: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 3

Chapter5:AtmosphereSpadeServer............................................................................................ 30

Chapter6:SupportfortheBayeuxProtocol ............................................................................... 32

WebServerdifferences ........................................................................................................................ 33

Page 4: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 4

IntroductionThe Atmosphere Framework is designed to make it easier to buildasynchronous/Comet‐based Web applications that include a mix of Comet andRESTfulbehavior.TheAtmosphereFrameworkisportableandcanbedeployedonany Web Server that supports the Servlet Specification 2.3. This documentintroducestheframeworkanditsmodule.Foranyquestionsorfeedback,[email protected]

Terminology• Suspend: The action of suspending consist of telling the underlying Web

Servertonotcommittheresponse,e.g.tonotsendbacktothebrowserthefinal bytes the browser is waiting for before considering the requestcompleted.

• Resume: The action of resuming consist of completing the response, e.g.committingtheresponsebysendingbacktothebrowserthefinalbytesthebrowseriswaitingforbeforeconsideringtherequestcompleted.

• Broadcast: The action of broadcasting consists of producing an event anddistributingthateventtooneormanysuspendedresponse.Thesuspendedresponsecanthendecidetodiscardtheeventorsenditbacktothebrowser.

• Long Polling: Long polling consists of resuming a suspended response assoonaseventisgettingbroadcasted.

• Http Streaming: Http Streaming, also called forever frame, consists ofresuming a suspended response after multiples events are gettingbroadcasted.

• NativeAsynchronousAPI:AnativeasynchronousAPImeansanAPIthatisproprietary, e.g. if youwrite an application using that API, the applicationwillnotbeportableacrossWebServer.

NoteIfyouhaveusedpreviousversionorAtmospherelike0.3.1,wehavereformulatedandred‐designedtheAtmosphereHandler.PleasereadthedocumenttitledMigratingyourAtmosphereApplicationfrom0.3.xto0.4.

Page 5: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 5

WhatistheAtmosphereFramework?The Atmosphere Framework contains several modules, which can be useddependingonyourneeds:

• AtmosphereRuntime(CometPortableRuntime):ThismodulecanbeusedtowritePOJOwritteninJava,JRubyorGroovy.Themaincomponentofthismodule is an AtmosphereHandler. An AtmosphereHandler can be used tosuspend, resume and broadcast and allow the use of the usualHttpServletRequestandHttpServletResponsesetofAPI.

• AtmosphereAnnotations:Thismoduledefines thesetofannotations thatcan be implemented to support Atmosphere concepts. By default, theAtmosphere Jerseymodule implements them, but any framework can alsoaddanimplementation.

• Atmosphere Jersey: This module can be used to write REST &AsynchronousWebapplication. TheRESTengineused is Jersey (Sun’s JAXRSimplementation).

• Atmosphere Meteor: This module can be used with existing Servlet orServletbased technology like JSP, JSF, Struts, etc.Themaincomponent isaMeteorthatcaneasilybelookedupfromanyJavaObject.

• AtmosphereBayeux:Thismodulesupporttheworkdonebythecomed.orggroup:TheBayeuxProtocol.

• AtmosphereGuice:ThismoduleallowtheuseofGoogleGuicetoconfigureyourAtmosphereapplication

Thistutorialwillcoverindetailsallofthem.TheFrameworkalsocontainsplug‐inthatcanbeaddedonthefly:

• Shoal Plug‐in: Allow the creation of Atmosphere Cluster using the ShoalFramework.

• JGroupsPlug‐in:AllowthecreationofAtmosphereClusterusingtheJGroupsFramework

• JMS Plug In: Allow the creation of Atmosphere Cluster using JMSQueue/Topics

• Grizzly Plug In: Allow Atmosphere application to be natively embeddedwithin the Grizzly Framework. A single builder API is available to helpembeddinganAtmospherebasedapplication.

The Framework also contains it’s own ready to use Web Server named theAtmosphere Spade Server, which consist of an end to end stack containing theGrizzlyWebServer,JerseyandallAtmospheremodulesandPlug‐in.

The Atmosphere Framework supports natively the following Web ServerasynchronousAPI:

• WebLogic’sAbstractAsyncServlet

Page 6: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 6

• Tomcat’sCometProcessor• GlassFish’sCometHandler• Jetty’sContinuation• JBoss’HttpEvent• Grizzly’sCometHandler• Servlet3.0’sAsyncListener• GoogleAppEnginerestrictedenvironment.

If Atmosphere fails to detect the above native API, it will instead use its ownasynchronous API implementation, which will consist of blocking a Thread persuspendedconnections.ThatmeansAtmosphereapplicationsareguaranteetoworkonanyWebServersupportingtheServletspecificationversion2.3andup.NotethatitisalsopossibletowriteyourownnativeimplementationandreplacetheoneusedbydefaultinAtmospherebyprovidinganimplementationoftheCometSupportSPI.Seenextsectionformoreinformation.

GettingstartedIndependent of themodule youdecide to use, the followingWAR file structure isrequiredwhenusingAtmosphere. SinceAtmosphereusesMaven as build system,youcanuseMaventogeneratetheskeletonforyourapplication:

% mvn archetype:create -DgroupId=sample -DartifactId=<YOUR_APP_NAME> -DarchetypeArtifactId=maven-archetype-webapp The web.xml here will be used to either define the AtmosphereServlet orMeteorServlet.InordertomakeyourapplicationportableamongstallWebServers,afilenamedcontext.xmlisrequired.Thefilecontains:

<Context> <Loader delegate="true"/>

</Context> This file is required in order to run inside the Tomcat and JBoss’ Web Server.TomcatwilllooksunderMETA‐INF/context.xml,JBossunderWEB‐INF/context.xml.IfyouarenotplanningtousethoseWebServer,thenyoudon’tneedtoaddthatfile.Butwe strongly recommend you always include it so you application is portableacrossWebServers.

To add support for the Atmosphere Framework, you need to define theAtmosphereServletorAtmosphereFilterinsideyourapplicationweb.xml:

<display-name>Atmosphere Servlet</display-name> <servlet> <description>AtmosphereServlet</description> <servlet-name>AtmosphereServlet</servlet-name> <servlet-class>org.atmosphere.cpr.AtmosphereServlet|AtmosphereFilter</servlet-class>

Page 7: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 7

<!-- Uncomment if you want to use Servlet 3.0 Async Support <async-supported>true</async-supported> --> <!—init-param are optional <init-param>org.atmosphere.*</init-param> <init-value> </init-value> --> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AtmosphereServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> Mainly, all you need to do is to define the AtmosphereServlet orAtmosphereFilter depending on how you want to use the framework. You canoptionallyconfiguresomeinit‐paramtheframeworkwilluse:

• org.atmosphere.useNative: You can tell the framework whichAsynchronousAPI:theWebServernativeoneorifavailable,theServlet3.0AsyncAPI.

• org.atmosphere.useBlocking: You can tell the framework to use blockingI/O approach instead of using the underlying Asynchronous Native API orServlet3.0.WhenusingblockingI/O,thecallingThreadwillblockassoonasyou suspend the response, andwill finish its execution once the responsegetsresumed.

• org.atmosphere.jersey.servlet­mapping: define the context‐root of aclass/resources,whichuseatmosphere‐core.

IMPORTANT: If you decide to use the framework using theAtmosphereFilter, beaware that only GlassFish, Grizzly and Jetty will take advantages of theirasynchronous native API. Tomcat, JBoss, WebLogic etc. will use the blocking I/Oapproach. IfyouneedtousetheAsynchronousNativeAPIallthetime,makesureyouwriteyourAtmosphereapplicationusetheAtmosphereServlet.

NotethatifyoudeployyourapplicationinsideaWebServerthatdoesn’thaveanyAsynchronous Native API, the framework will detect it and use a blocking I/Oapproach(ex:Resin).ThusyouarealwaysguaranteedthatyourapplicationcanbedeployedinsideanyWebServerthatsupporttheServletSpecification2.3andup.

An Atmosphere application can be configured using a file called atmosphere.xml,locatedunderMETA‐INF/.The file isoptional and the frameworkwillusedefaultvalue if not specified. Whennot specified, the frameworkwill scan classesunderWEB‐INF/classes and load and register the one that implement theAtmosphereHandler interface. The atmosphere.xml contains information aboutAtmosphereHandlerandtheirURLmapping,Broadcaster,Servlet,etc.Thefiletakestheformof:

<atmosphere-handlers> <atmosphere-handler context-root="/twitter" class-name="org.atmosphere.samples.twitter.TwitterAtmosphereHandler"/>

Page 8: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 8

<property name=”” value=””/> <atmosphere-handler …/> </atmosphere-handlers> Fromthatfile,Atmospherecanconfigureforanapplication:

• context­root: The context‐root used to map the request with theAtmosphereHandler.Asanexample,ifyouwanttomaparequestthattakesthe formof/foo/bar,youwillmapstheAtmosphereServlet to/foo,andsetthecontext‐rootto/bar.

• class­name: The full qualified name of your AtmosphereHandlerimplementation

• broadcaster: The full qualified name of your AtmosphereHandlerimplementation

• property: A name/value pair that can be used to configure anAtmosphereHandler.Asanexample,defining<propertyname="servletClass"value="foo"/> will invokes on the AtmosphereHandler.setServletClassmethod with the value defined. Any property can then be configured atruntimeusingproperty.

• comet­support:AnimplementationoftheCometSupportSPI.YoucandefineyourownCometimplementationthatwillbeusedbyyourapplication.

• session­support: By default, the Atmosphere Runtime uses Sessions tostoresomeinfo,butAtmosphereJerseybydefaultdoesn’tusesSessions.YoucanturnonSessionsbysettingthevaluetotrue.

AtmosphereMainConceptTherearereallythreemainoperationsanasynchronousapplicationmightrequire.The first one is the ability to suspend the execution of a request/responseprocessing until an asynchronous events occurs. Once the event occurs, youmaywant to resume the normal request/response processing, depending on thetechnique your application support (long polling or http streaming). The thirdoperation consists of being able to broadcast or push asynchronous events anddeliverthemtosuspendedresponses.

Page 9: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 9

Chapter1:AtmosphereJersey(AsynchronousRESTfulwebApplication)

TheConceptsAtmosphere Jersey isamodule thatallows thecreationofAsynchronousRESTFulwebservice.ThemoduleextendsProjectJersey,whichistheimplementationofJSR311(JAX‐RS).It isstronglyrecommendedtotakealookatJersey’sGettingStartedTutorialbeforereadingthissection.ThissectionwillnotexplainhowJerseyworksandwhatJAX‐RS/RESTfulwebservicesare.

An application that defines resources mapped to the root (“/”) isn’t by defaultrequired to have anMETA‐INF/atmosphere.xml file. The Atmosphere Frameworkwillauto‐detect the Jerseyruntimeandstart itautomatically,andwill register theresources defined to the “/” context‐root (see atmosphere.xml explanation inchapter2).Youcanalsospecifythecontext‐rootbyaddingthefollowinginit‐paramfortheAtmosphereServlet|Filter:

<init-param>org.atmosphere.core.servlet-mapping</init-param> <init-value>some value</init-value> Youcanalsodefinethefollowingatmosphere.xmlfiletoenableatmosphere‐jersey:

<atmosphere-handlers> <atmosphere-handler context-root="/dispatch" class-name="org.atmosphere.handler.ReflectorServletProcessor"> <property name="servletClass" value="com.sun.jersey.spi.container.servlet.ServletContainer"/> </atmosphere-handler> </atmosphere-handlers> AsexplainedinmoredetailsintheChapter2,theReflectorServletProcessorisusedtomanage the lifecycle of the Jersey’s ServletContainer. TheAtmosphere runtimewillloadthatServlet,andwillextendsJerseyinternalwithasetofannotationsthatwillallowthecreationofAsynchronousRESTfulapplication.Theoperationswearetheabilitytosuspend,resume,scheduleandbroadcastevent.

Page 10: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 10

@SuspendThe@Suspendannotationallowsuspendingtheprocessingoftheresponse.Youcanannotate anyResource’smethodwith the@Suspend annotation,which is definedas:

public @interface Suspend { int period() default -1; enum SCOPE { REQUEST, APPLICATION, VM } SCOPE scope() default SCOPE.APPLICATION; boolean outputComments() default true; public boolean resumeOnBroadcast() default false; public Class<? extends AtmosphereResourceEventListener>[] listeners() default {};

Theperiod represent the time in second a responsewill stay suspendedwithoutanyeventsoccurring,orwithoutresumingtheresponse.The scope concept is explained in more details later in this chapter: can aBroadcaster be used for broadcasting events to its associated request, to allsuspendedresponsewithintheapplicationortoallsuspendedresponsesavailableon theVM.Note that theBroadcasterwill be created after the annotatedmethodgetsexecuted.TheoutputComments isusedtotellstheframeworktonotoutputanycommentswhen the response gets suspended. By default, Atmosphere always output somecomments to make browsers based on WebKit (Chrome, Safari) works properlywhenaresponseissuspended.The resumeOnBroadcast tells Atmosphere to resume the response as soon as aBroadcastoperationsoccurs.Youusually set it to true if yourplanning touse thelongpollingComettechnique.The listeners() is a set of class that implements thatAtmosphereResourceEventListener, which can be used to monitor Atmosphereeventslikedisconnect,resumeandbroadcast.TheAPIisdefinedas:

voidonResume(AtmosphereResourceEventevent);voidonDisconnect(AtmosphereResourceEventevent);voidonBroadcast(AtmosphereResourceEventevent);

Page 11: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 11

TheonResumewillbeinvokedwhentheresponseisresuming,eitherbecausetheperiodtimeoutorthe@Resumeannotationwasbeenexecuted.TheonDisconnectwillbeinvokedwhentheremoteclientclosetheconnection.NotethatnotallWebServer support client disconnection detection. Refer to Annex A for moreinformation.TheonBroadcastwill be invoked every time a broadcast operationsoccurs.Usuallyyouusethatannotationbydoing:

@Suspend(default=60)

@ResumeThe@ResumeannotationistheequivalenceofAtmosphereResource.resume.Youcanannotateanyresource’smethodwiththe@Resumeannotation,whichisdefinedas:

public @interface Resume { int count() default 1; // long polling }

ThecountrepresentthenumberofBroadcasteventthatneedtohappensbeforethesuspendedresponsegetsresumed.Usuallyyouusethatannotationbydoing:

@Resume

@BroadcastOnce of the key concept of the Atmosphere Framework is called Broadcaster. ABroadcastercanbeusedtobroadcast(orpushback)asynchronouseventstothesetorsubsetofsuspendedresponses.ABroadcastercanbeusedwheneventsarereadyto be written back to the browser. A Broadcaster can contain zero or moreBroadcastFilter,whichcanbeusedtotransformtheeventsbeforetheygetwrittenback to thebrowser.Forexample, anymalicious characters canbe filteredbeforetheygetwrittenback.ABroadcastercancontainzerooroneSerializer.ASerializerallowsanapplicationtodecidehowtheeventwillbeserializedandwrittenbacktothe browser. When no Serializer is defined, the HttpServletResponse’s outputstreamwill be used and the event written as it is. Hence, firing a broadcast willproducethefollowingchainofinvocation:

broadcast BroadcastFilter(s) Serializer AtmosphereResourceEvent.onStateChange

Page 12: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 12

TheAPIlookslike:

public interface Broadcaster {

public Future<Object> broadcast(Object o); public Future<Object> delayBroadcast(Object o); public Future<Object> delayBroadcast(Object o, long delay, TimeUnit t); public Future<?> scheduleFixedBroadcast(Object o, long period, TimeUnit t); public Future<Object> broadcast(Object o, AtmosphereResource event); public Future<Object> broadcast(Object o, Set<AtmosphereResource> subset);

Internally, a Broadcaster uses an ExecutorService to execute the above chain ofinvocation.Thatmeansacall toBroadcaster.broadcast(..)willnotblockunlessyouusethereturnedFutureAPI,andwilluseasetofdedicatedthreadstoexecutethebroadcast. By default, an ExecutorServices will be created and the number ofthreads will be based on the OS’ core/processor (usually 1 or 2). You can alsoconfigureyourownExecutorServicesusingaBroadcasterConfig.

ABroadcastercanalsobeusedtobroadcastdelayedevents,e.g.anapplicationcandecide to delay an events until another events happens or after a delay. This isparticularlyusefulwhenyouneedtoaggregateeventsandwritethemallinonce.

ABroadcaster canalsobeused tobroadcastperiodic events. It canbe configuredusing an ScheduledExecutorService to produce periodic events. As with theExecutorService, the number ofOS’ core/processorwill be used to determine thedefault number of threads. You can also configure your ownSchedulerExecutorServiceviatheBroadcastConfig.

One finalword on Broadcaster: by default, a Broadcasterwill broadcast using allAtmosphereResourceEvent on which the response has been suspended, e.g.AtmosphereResource.suspend()hasbeeninvoked.ThisbehaviorisconfigurableandyoucanconfigureitbyinvokingtheBroadcaster.setScope():

• REQUEST: broadcast events only to the AtmosphereResourceEventassociatedwiththecurrentrequest.

• APPLICATION:broadcasteventstoallAtmosphereResourceEventcreatedforthecurrentwebapplication

• VM: broadcast events to all AtmosphereResourceEvent created inside thecurrentvirtualmachine.

The default is APPLICATION. Broadcaster are retrieved using anAtmosphereResource.getBroadcaster() or can also be looked up from any JavaobjectsusingBroadcasterLookup.

Page 13: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 13

Anapplicationcandefineitsownimplementationandtell theframeworktouse itbydeclaringitinsideatmosphere.xml:

<atmosphere-handlers> <atmosphere-handler.. broadcaster="org.atmosphere.samples.twitter.TwitterBroadcaster"/> The@BroadcastannotationistheequivalenceofAtmosphereResource.getBroadcaster’s.Youcanannotateanyresource’smethodwiththe@Broadcastannotation,whichisdefinedas:

public @interface Broadcast { public Class<? extends BroadcastFilter>[] value()

default {}; public boolean resumeOnBroadcast() default false; public int delay() default -1; }

ThevaluefielddefineswhichBroadcastFilterneedstobeaddedtotheBroadcasterassociatedwiththecurrentsuspendedresponse.TheresumeOnBroadcastmeansthattheresponsewillberesumedassoonasaneventisbroadcasted.Thedelaycanbeusedtodelaytheexecutionoftheevents,whichisthesameasdoingBroadcaster.delay(…).Usuallyyouusethatannotationbydoing:

@Broadcast({XSSHtmlFilter.class,JsonpFilter.class})YoucanalsobroadcastanytypeofobjectbyusingaBroadcastable.ABroadcastablewill tell the framework tobroadcasteventusing theBroadcasterand theObjectaBroadcastablerepresents: @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces("text/html") @Broadcast public Broadcastable onPush() Broadcastable b = new Broadcastable(m, bc); return b; } Notethatyoucanbroadcastanytypereturnedbythe@Producedannotation:

@POST @Path("{counter}") @Produces({"application/xml", "application/json"}) public MyEvent resume(){ return new MyEvent("POST"); }

Page 14: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 14

InjectableObjectsYoucanalsoinjectatruntimeBroadcaster,AtmosphereResourceEventandBroadcasterLookupinstancebyusingtheJersey’s@Contextannotation: @ContextBroadcasterbc @ContextAtmosphereResourceEvente @ContextBroadcasterLookupbSeethePubSubsampleforaneasytounderstandsample.

WritingasimpleChatapplicationusingAtmosphereJerseyLet’s re‐write the Chat application we described using atmosphere‐runtime. Thecomplete source of the following sample can be downloaded fromatmosphere.dev.java.net.First,let’sgeneratetheprojectusingMaven.

% mvn archetype:create -DgroupId=org.atmosphere.samples -DartifactId=chat -DarchetypeArtifactId=maven-archetype-webapp Whichwillcreatethefollowingstructure:

./chat ./chat/pom.xml ./chat/src ./chat/src/main ./chat/src/main/resources ./chat/src/main/webapp ./chat/src/main/webapp/index.jsp ./chat/src/main/webapp/WEB-INF ./chat/src/main/webapp/WEB-INF/web.xml

Nextlet’seditourpom.xmlanddefinestheatmosphere‐coreandit’sdependencies <dependency> <groupId>org.atmosphere</groupId> <artifactId>atmosphere-core</artifactId> <version>${atmosphere-version}</version> </dependency> As for any Atmosphere application, you define the AtmosphereServlet inside theweb.xml: <servlet> <description>AtmosphereServlet</description> <servlet-name>AtmosphereServlet</servlet-name> <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class> <!-- Uncomment if you want to use Servlet 3.0 Async Support <async-supported>true</async-supported> --> </servlet> <servlet-mapping> <servlet-name>AtmosphereServlet</servlet-name> <url-pattern>/resource/*</url-pattern> </servlet-mapping> Nextwecaneitherdefinetheatmosphere.xml:

<atmosphere-handlers> <atmosphere-handler context-root="/resources"

Page 15: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 15

class-name="org.atmosphere.handler.ReflectorServletProcessor"> <property name="servletClass" value="com.sun.jersey.spi.container.servlet.ServletContainer"/> </atmosphere-handler> </atmosphere-handlers>

Oraddtheorg.atmosphere.core.servlet‐mappinginit‐paramundertheAtmosphereServletdefinedabove <init-param> <param-name>org.atmosphere.core.servlet-mapping</param-name> <param-value>/resources</param-value> </init-param>

Nowlet’susetheannotationdefinedintheprevioussection:

@Suspend @GET @Produces("text/html;charset=ISO-8859-1") public String suspend() { return “”; } @Broadcast({XSSHtmlFilter.class, JsonpFilter.class}) @Consumes("application/x-www-form-urlencoded") @POST @Produces("text/html;charset=ISO-8859-1") public String publishMessage(MultivaluedMap<String, String> form) { String action = form.getFirst("action"); String name = form.getFirst("name"); if ("login".equals(action)) { return ("System Message" + "__" + name + " has joined."); } else if ("post".equals(action)) { return name + "__" + form.getFirst("message"); } else { throw new WebApplicationException(422); } } @Schedule(period=30) @POST @Path("/ping") public String pingSuspendedClients(){ return "Atmosphere__ping"; } Thewayitworksisassoonthesuspendmethodwillbeinvoked,itsreturnsvaluewillbewrittenback(hereempty)totheclientandtheresponsesuspended.WhenthepublishMessagewillbe invoked, itsreturnedvaluewillbebroadcasted,e.g.allsuspendedresponseswillbeinvokedandthevaluewrittenasitistotheclient.Wealsoaddedsupportfor“ping”,whichisenabledbythe@ScheduleannotationofthepingSuspendedClients.Thecompletecodecanbebrowsedfromhere.

Page 16: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 16

Chapter2:AtmosphereRuntime(CometPortableRuntime)

TheconceptsTheAtmosphere runtime is the foundationof the Framework.All othersmodulesbuildontopofit. ThemaincomponentiscalledanAtmosphereHandleranditisdefinedas:

public interface AtmosphereHandler<F,G> { public void onRequest(AtmosphereResource<F,G> event)

throws IOException;

public void onStateChange(AtmosphereResourceEvent<F,G> event) throws IOException;

}

The onRequest is invoked every time a request urimatch the context‐root of theAtmosphereHandler defined within the definition of the AtmosphereHandler inatmosphere.xml:

<atmosphere-handlers> <atmosphere-handler context-root="/twitter" class-name="org.atmosphere.samples.twitter.TwitterAtmosphereHandler"/> </atmosphere-handlers>

AtmosphereResourceThe main object to interact with when the onRequest is executed is anAtmosphereResource. An AtmosphereResource can be used to manipulate thecurrentrequestandresponseandusedtosuspendorresumearesponse,andalsobroadcastevents.

public interface AtmosphereResource<E,F> {

public void resume();

public void suspend();

public void suspend(long timeout);

public E getRequest();

public F getResponse();

public AtmosphereConfig getAtmosphereConfig();

public Broadcaster getBroadcaster();

public void setBroadcaster(Broadcaster broadcaster);

public void setSerializer(Serializer s);

public void write(OutputStream os, Object o) throws IOException;

public Serializer getSerializer();

Page 17: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 17

AtmosphereResourceEventAn AtmosphereResourceEvent contains the state of the response, e.g. has theresponsebeensuspended,resumed,etc.APIlookslike:

public interface AtmosphereResourceEvent<E,F> { public void resume(); public boolean isResumedOnTimeout(); public boolean isCancelled(); public boolean isSuspended(); public boolean isResuming(); public Object getMessage(); public void write(OutputStream os, Object o) throws IOException;

TheAtmosphereHandler’sonStateChangeisinvokedwhen:

• AneventisbroadcastedusingaBroadcaster(moreonthetopicbelow)• Aneventisabouttoresumebasedonatimeout• Abrowser closes the remote connection.Not allWeb Server supports that

mechanism.SeeAnnexAformoreinfo.

ReadytouseAtmosphereHandlerAn Atmosphere application can consist of one or more AtmosphereHandler. TheFramework contains two implementations of that interface. The first is calledAbstractReflectorAtmosphereHandlerandcontainsadefault implementationfortheonMessagemethod.TheonMessageinthatcasereflectthebroadcastedevent,e.g.itwrites the broadcasted event without any modification. If a Serializer has beenconfigured, the Serializer will be used for writing the event. If none, theHttpServletResponsewriter(oroutputstream)willbeused.

ThesecondimplementationisRefectorServletProcessorandcanbeusedtoexecuteServlet fromanAtmosphereHandler.AReflectorServletProcessorwill forward therequest to the Servlet.service() method of a Servlet and also make available theassociatedAtmosphereResourceEventtotheServlet.ThatwayanyexistingServletcan use the Atmosphere Framework by retrieving the AtmosphereResourceEventfromtheHttpServletRequest.getAttributeusing:

org.atmosphere.runtime.AtmosphereResource

asakey:HttpServletRequest.getAttribute(“org.atmosphere.runtime.AtmosphereResource”).

ThisAtmosphereHandlerishelpfulwhenyouneedtorunanotherframeworkontopofAtmosphere.Ifyouareplanningtousetheframeworkfromanexistingapplication,takealookatChapter3fortherecommendedway.YoudefinetheReflectorServletProcessorinatmosphere.xmlandit’sassociatedServletbydoing:

Page 18: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 18

<atmosphere-handlers> <atmosphere-handler context-root="/dispatch" class-name="org.atmosphere.handler.ReflectorServletProcessor" <property name="servletClass" value="com.sun.jersey.spi.container.servlet.ServletContainer"/> </atmosphere-handler> </atmosphere-handlers> YouneedtodefineapropertycalledservletClassandsetyourServlet’sfullyqualifiedclassname.

Page 19: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 19

WritingasimpleChatapplicationusingAtmosphereruntimeThecompletesourceofthefollowingsamplecanbedownloadedfromatmosphere.dev.java.net.First,let’sgeneratetheprojectusingMaven.

% mvn archetype:create -DgroupId=org.atmosphere.samples -DartifactId=chat -DarchetypeArtifactId=maven-archetype-webapp Whichwillcreatethefollowingstructure:

./chat

./chat/pom.xml

./chat/src

./chat/src/main

./chat/src/main/resources

./chat/src/main/webapp

./chat/src/main/webapp/index.jsp

./chat/src/main/webapp/WEB-INF

./chat/src/main/webapp/WEB-INF/web.xml Nextlet’seditourpom.xmlanddefinestheatmosphere‐runtimeandit’sdependencies <dependency> <groupId>org.atmosphere</groupId> <artifactId>atmospher-runtime</artifactId> <version>${atmosphere-version}</version> </dependency> WearenowreadytowriteourfirstAtmosphereHandler,whichisthecentralpieceofanyAtmosphereruntimeapplication.Let'sjustimplementthisinterface: public void onRequest (AtmosphereResource<HttpServletRequest,HttpServletResponse> event) throws IOException { HttpServletRequest req = event.getRequest(); HttpServletResponse res = event.getResponse();

if (req.getMethod().equalsIgnoreCase("GET")) { event.suspend();

Broadcaster bc = event.getBroadcaster(); bc.getBroadcasterConfig().addFilter(new XSSHtmlFilter()); Future<Object> f = bc.broadcast( event.getAtmosphereConfig().getWebServerName() + "**has suspended a connection from " + req.getRemoteAddr()); try {

// Wait for the push to occurs. // This block the current Thread f.get();

} catch (Throwable t) { } bc.scheduleFixedBroadcast(req.getRemoteAddr()

Page 20: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 20

+ "**is connected", 30, TimeUnit.SECONDS); bc.delayBroadcast("Underlying Response now suspended"); The central piece is the AtmosphereResource, from which we can retrieve therequestandresponseobject.Nextwedosomesetupandthenoncewearereadywejust need to invoke the AtmosphereResourceEvent.suspend, which willautomaticallytellAtmosphereruntimetonotcommittheresponse.Notcommittingtheresponsemeanswecanre‐useitlaterforwriting.Inthecurrentsample,wewillusethesuspendedresponsewhensomeoneenterjoinorentersentenceinsidethechatroom.Nowlet'sassumewhenauserlogsinorentersentences,thebrowsersetaPOST(postingsomedata).Sowhenauserlogsin:

} else if (req.getMethod().equalsIgnoreCase("POST")) { res.setCharacterEncoding("UTF-8"); String action = req.getParameterValues("action")[0]; String name = req.getParameterValues("name")[0]; if ("login".equals(action)) {

event.getBroadcaster().broadcast(WELCOME_MSG + event.getAtmosphereConfig().getWebServerName() + "**" + name + " has joined.");

res.getWriter().write("success"); res.getWriter().flush(); SinceBroadcaster'sroleistopublishdatatothesuspendedresponses,assoonaswebroadcastdata,allsuspendedresponseswillbegivenachancetowritethecontentofthebroadcastwhentheAtmosphereHandler.onStateChangegetsinvoked.AbovewejustbroadcastthenameandalsowhichWebServerwearerunningonHerelet'sassumewejustreflect(write)whatwereceive,sowejustimplementsinsidetheonStateChange:

public void onStateChange( AtmosphereResourceEvent<HttpServletRequest,

HttpServletResponse> event) throws IOException {

HttpServletRequest req = event.getResource().getRequest(); HttpServletResponse res = event.getResource().getResponse(); String msg = (String)event.getMessage(); if (event.isCancelled()){ event.getResource().getBroadcaster().broadcast(

req.getSession().getAttribute("name").toString() + " has left");

} else if (event.isResuming() || event.isResumedOnTimeout()) { String script =

"<script>window.parent.app.listen();\n</script>"; res.getWriter().write(script); res.getWriter().flush(); } else { res.getWriter().write(msg);

Page 21: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 21

res.getWriter().flush(); } return event; Intheabovecodewemakejustcheckiftheeventhasbeencancelled(becausethebrowserclosedtheconnection)orresumed,andifnotwejustwritethebroadcastedmessage.Now let's assume we want to have a more fine grain way to map ourAtmosphereHandler to the request. To achieve that, create a file calledatmosphere.xmlundersrc/main/webapp/META‐INF/anddefinethemappingyouwant: <atmosphere-handlers> <atmosphere-handler context-root="/chat" class-name="org.atmosphere.samples.chat.ChatAtmosphereHandler"> <property name="name" value="Chat"/> </atmosphere-handler> </atmosphere-handlers> Nowlet'sexploretheclientside.First,let'swriteaverysimpleindex.htmlfile:<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Atmosphere Chat</title> <link rel="stylesheet" href="stylesheets/default.css" type="text/css" /> <script type="text/javascript" src="javascripts/prototype.js"></script> <script type="text/javascript" src="javascripts/behaviour.js"></script> <script type="text/javascript" src="javascripts/moo.fx.js"></script> <script type="text/javascript" src="javascripts/moo.fx.pack.js"></script> <script type="text/javascript" src="javascripts/application.js"></script> </head> <body> <div id="container"> <div id="container-inner"> <div id="header"> <h1>Atmosphere Chat</h1> </div> <div id="main"> <div id="display"> </div> <div id="form">

Page 22: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 22

<div id="system-message">Please input your name:</div> <div id="login-form"> <input id="login-name" type="text" /> <br /> <input id="login-button" type="button" value="Login" /> </div> <div id="message-form" style="display: none;"> <div> <textarea id="message" name="message" rows="2" cols="40"></textarea> <br /> <input id="post-button" type="button" value="Post Message" /> </div> </div> </div> </div> </div> </div> <iframe id="comet-frame" style="display: none;"></iframe> </body> </html> Simpleformthatwillsendbacktotheserverthelogin'snameandthechatmessageentered. To update on the fly the interface as soon as ourChatAtmosphereHandler.onStateChangewrite/sendusdata,let'suseprototypeandbehavior javascript. Below we are assuming you are either familiar with thoseframeworksorhavebasicunderstandinghowtheywork.Thiswillbedefinedunderapplication.js.Assoonastheuserenteritsloginname,let'sdo post: function() { var message = $F('message'); if(!message > 0) { return; } $('message').disabled = true; $('post-button').disabled = true; var query = 'action=post' + '&name=' + encodeURI($F('login-name')) + '&message=' + encodeURI(message); new Ajax.Request(app.url, { postBody: query, onComplete: function() { $('message').disabled = false; $('post-button').disabled = false; $('message').focus(); $('message').value = ''; } }); }, Whentheuserwritenewchatmessage,let'spush

Page 23: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 23

post: function() { var message = $F('message'); if(!message > 0) { return; } $('message').disabled = true; $('post-button').disabled = true; var query = 'action=post' + '&name=' + encodeURI($F('login-name')) + '&message=' + encodeURI(message); new Ajax.Request(app.url, { postBody: query, onComplete: function() { $('message').disabled = false; $('post-button').disabled = false; $('message').focus(); $('message').value = ''; } }); } Nowwhenwegetresponse,wejustupdatethepageusing update: function(data) { var p = document.createElement('p'); p.innerHTML = data.name + ':<br/>' + data.message; $('display').appendChild(p); new Fx.Scroll('display').down(); } Thewaytheindex.htmlandapplication.jsinteractissimplydefinedby:

var rules = { '#login-name': function(elem) { Event.observe(elem, 'keydown', function(e) { if(e.keyCode == 13) { $('login-button').focus(); } }); }, '#login-button': function(elem) { elem.onclick = app.login; }, '#message': function(elem) { Event.observe(elem, 'keydown', function(e) { if(e.shiftKey && e.keyCode == 13) { $('post-button').focus(); } }); }, '#post-button': function(elem) { elem.onclick = app.post;

Page 24: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 24

} }; Behaviour.addLoadEvent(app.initialize); Behaviour.register(rules);

Finally,justdeployyourwarfileintoanyWebServerandseethefinalresult.

Page 25: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 25

Chapter3:AtmosphereMeteor

TheConceptsThe Atmosphere Meteor module allows any existing Servlet based application(Wicket,JSP,JSF,etc.)toeasilyaddasynchronoussupport.YouenableAtmosphereMeteorbyaddingtheMeteorServletinsideyourweb.xml: <servlet> <description>MeteorServlet</description> <servlet-name> MeteorServlet </servlet-name> <servlet-class>org.atmosphere.runtime.MeteorServlet</servlet-class> <init-param> <param-name>org.atmosphere.servlet</param-name> <param-value>…</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name> MeteorServlet </servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> TheMeteorServletcanbeconfiguredusingtwoormoreinit‐param:

• org.atmosphere.servlet:TheMeteorServletwillinvoketheServletandallowthemtosuspend,resumeandbroadcastevent.

• org.atmosphere.filter:TheMeteorServletwill invokethoseFiltersandallowthemtosuspend,resumeandbroadcastevent.

Unlike atmosphere‐runtime and atmosphere‐core module, this module doesn’trequireanyatmosphere.xmlconfigurationfile.NowfromanyFiltersandServlet,allyouneedtodoistointeractwiththeMeteorAPI:

publicfinalstaticMeteorbuild(HttpServletRequestr,List<BroadcastFilter>l,Serializers)publicMeteorsuspend(longl)publicMeteorresume()publicMeteorbroadcast(Objecto)publicvoidaddListener(AtmosphereResourceEventListenere)

Allyouneedtodo is togetan instanceofaMeteorby invokingthebuildmethod,andpassinganinstanceoftherequestyoueventuallywanttosuspenditsassociatedresponse. You can optionally pass your set of BroadcastFilter as well as aSerializer.

Page 26: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 26

WritingasimpleChatapplicationusingAtmosphereMeteorLet’s re‐write the Chat application we described using atmosphere‐runtime. Thecomplete source of the following sample can be downloaded fromatmosphere.dev.java.net.First,let’sgeneratetheprojectusingMaven.

% mvn archetype:create -DgroupId=org.atmosphere.samples -DartifactId=chat -DarchetypeArtifactId=maven-archetype-webapp Whichwillcreatethefollowingstructure:

./chat

./chat/pom.xml

./chat/src

./chat/src/main

./chat/src/main/resources

./chat/src/main/webapp

./chat/src/main/webapp/index.jsp

./chat/src/main/webapp/WEB-INF

./chat/src/main/webapp/WEB-INF/web.xml

Next,let’sdefineourMeteorServletaswellasourServletinsidetheweb.xml:

<description>Atmosphere Chat</description> <display-name>Atmosphere Chat</display-name> <servlet> <description>MeteorServlet</description> <servlet-name>MeteorServlet</servlet-name> <servlet-class>org.atmosphere.runtime.MeteorServlet</servlet-class> <init-param> <param-name>org.atmosphere.servlet</param-name> <param-value>org.atmosphere.samples.chat.MeteorChat</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MeteorServlet</servlet-name> <url-pattern>/Meteor</url-pattern> </servlet-mapping>

NowwejustneedtowriteasimpleServletlikethefollowing:public class MeteorChat extends HttpServlet { /** * List of {@link BroadcastFilter} */ private final List<BroadcastFilter> list; public MeteorChat() { list = new LinkedList<BroadcastFilter>(); list.add(new XSSHtmlFilter()); list.add(new JsonpFilter()); } @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws

IOException{ Meteor m = Meteor.build(req, list, null); req.getSession().setAttribute("meteor", m); m.suspend(-1);

Page 27: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 27

m.broadcast(req.getServerName() + "__has suspended a connection from " + req.getRemoteAddr()); } @Override public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException { Meteor m = (Meteor)req.getSession().getAttribute("meteor"); res.setCharacterEncoding("UTF-8"); String action = req.getParameterValues("action")[0]; String name = req.getParameterValues("name")[0]; if ("login".equals(action)) { req.getSession().setAttribute("name", name); m.broadcast("System Message from " + req.getServerName() + "__"

+ name + " has joined."); res.getWriter().write("success"); res.getWriter().flush(); } else if ("post".equals(action)) { String message = req.getParameterValues("message")[0]; m.broadcast(name + "__" + message); res.getWriter().write("success"); res.getWriter().flush(); } else { res.setStatus(422); res.getWriter().write("success"); res.getWriter().flush(); } } }

As you can see, using a Meteor is simple and should be used from any existingServlet.OnceyouhaveaMeteor,youcansuspend,resumeandbroadcasteventslikeyou can do with Atmosphere runtime or core module. The client side for theexampleaboveisthesameasdescribedinChapter1withatmosphere‐runtime.

Page 28: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 28

Chapter4:AtmospherePlugIn

AtmosphereGrizzlyPlugIn

UseProjectGrizzlyWebFrameworktoembedAtmosphereThispluginallowyoutoprogrammaticallyaddAtmospheresupporttotheProjectGrizzly’sWebServerembedAPI.YoucanlearnmoreaboutProjectGrizzlyanditsWebFrameworkbygoingtotheirhomepage.TheAtmosphereimplementationiscalledAtmosphereAdapterandcanbeusedwithGrizzlyWebServerbydoing:

GrizzlyWebServer ws = new GrizzlyWebServer();

AtmosphereAdapter a = new AtmosphereAdapter();

a.addAtmosphereHandler(new AtmosphereHandler()..);

ws.addGrizzlyAdapter(a);

ws.start();

Youcanalsoenableatmosphere‐corebydoing:

GrizzlyWebServer ws = new GrizzlyWebServer();

AtmosphereAdapter a = new AtmosphereAdapter();

a.setResource(“my.resource.package”);

ws.addGrizzlyAdapter(a);

ws.start();

DeployingyourAtmosphereAdapterusingGlassFishYoucanalsodeployanAtmosphereAdapterinsideGlassFishv3Nucleusdistributionwithouttheneedstobundlesyourapplicationinsideawarfileandwithouttheneedofweb.xml.AllyouneedtodoistocreateaMETA­INF/grizzly­glassfish.xmlandregisteryourAtmosphereAdapter:

<adapters> <adapter context-root="/atmosphere" class-name="org.atmosphere.grizzly.AtmosphereAdapter"/>

</adapters>

ThenyoucandeployyourjarintoGlassFishv3usingtheadmintoolorsimplydoing

java –jar glassfish.jar yourAtmosphereApplication.jar

Page 29: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 29

AtmosphereClusterPlugInAnyAtmosphereapplicationcanbedeployedinsideaclusterusingtheAtmosphereClusterPlugIn.Theframeworkcurrentlysupportsthefollowingclusterframework:

• Shoal• JGroups• JMS

ClusteringsupportinAtmosphereissupportedusingBroadcastFilter.Hence,toaddsupportforclustering,allyouneedtodoaddtheBroadcastFiltertoyourBroadcaster:

Broadcaster bc = event.getBroadcaster(); bc.addBroadcastFilter(new ShoalFilter());

AnyBroadcastoperationswillbebroadcastedtoallyourAtmosphereapplicationsdeployedinsideyourcluster.Ifyouuseatmosphere‐core,allyouneedtodoistoannotateyourmethodwiththe@Clusterannotation:

@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.runtime) @Documented public @interface Cluster {

String name() default "Atmosphere"; Class<? extends org.atmosphere.runtime.ClusterBroadcastFilter>[] value()default {org.atmosphere.runtime.ClusterBroadcastFilter.class};

Youusetheannotationbydoing:

@Broadcast @Consumes("application/x-www-form-urlencoded") @POST @Produces("text/html") @Cluster(name="chat,value=ShoalFilter|JgroupsFilter|JMSFilter”) public String publishMessage(MultivaluedMap form) {

Page 30: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 30

Chapter5:AtmosphereSpadeServerTheAtmosphereSpaceServerisanend‐to‐endstackthataggregatetechnologylike:

• Grizzly’sServletContainer• Jersey• Atmosphereruntime,JerseyandMeteor• AtmospherePlug‐in

Theserverisbundledinsideasinglejarandcanbeusedusingthecommandline:

java –jar atmosphere-spade-server.jar …

Usage: org.atmosphere.spade.AtmosphereSpadeLauncher [options] -p, --port=port Runs Atmosphere on the specified port. Default: 8080 -a, --apps=application path The AtmosphereServlet folder or jar or war

location. Default: . -rp, --respourcespackage=package The resources package name Default: -sp, --servletPath=path The path AtmosphereServlet will serve

resources Default: . -h, --help Show this help message.

Theservercanalso beembeddedintoanyapplicationusingtheAtmosphereSpadeServerAPI:

public static AtmosphereSpadeServer build(String u) public static AtmosphereSpadeServer build

(String u, String resourcesPackage) public AtmosphereSpadeServer addAtmosphereHandler

(String mapping,AtmosphereHandler h

public void setResourcePackage(String resourcePackage) public AtmosphereSpadeServer start() throws IOException public AtmosphereSpadeServer stop() throws IOException

YoucanbuildAtmosphereSpadeServerbyjustdoing:

AtmosphereSpadeServer.build(“http://localhost:8080”).start();

YoucanconfiguretheAtmosphereSpadeServertodeployyourAtmosphereHandler:

AtmosphereSpadeServer.addAtmosphereHandler(“/chat”,newChatAtmoshereHandler);

Page 31: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 31

AtmosphereSpadeServercanalsobeusedwithatmosphere‐corebyeitherpassingthepackagenameofyourresource:

AtmosphereSpadeServer.build(“http://localhost”,”org.atmosphere”);

Page 32: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 32

Chapter6:SupportfortheBayeuxProtocolTheBayeuxProtocolisapub/subprotocoldevelopedbytheCometd.org.Ifyouarenot familiar with the Bayeux protocol, I recommend you read the specificationbeforereadingthatchapter.

Bydefault, theCometd.org implementationusesablocking threadapproachwhensuspending responses, except when deployed on Jetty. The reason is the maindeveloperofCometd.org isalso the leadof Jetty. TheAtmosphereBayeuxPlug Infixesthatissuebyrunningontopofatmosphere‐runtime,whichalwaysusesnativeCometImplementationbeforeblockingathreadtosuspendtheresponse.Blockingathread per request may cause serious performance issue when too may threadsneedtobecreated.AtmosphereBayeuxPlugIntherescue!

TodeployyourBayeuxapplicationusingAtmosphere,you firstneed todefine thefollowingatmosphere.xml<atmosphere-handlers> <atmosphere-handler context-root="/cometd" class-name="org.atmosphere.handler.ReflectorServletProcessor"> <property name="servletClass" value="org.atmosphere.plugin.bayeux.AtmosphereBayeuxServlet"/> </atmosphere-handler> </atmosphere-handlers>

Here you just tell the ReflectorServletProcessor to use theAtmosphereBayeuxServlet,whichisanextensiontothenormalCometd.orgServletimplementation.Nextistodefineinweb.xmltheAtmosphereServletthesamewayyouwouldhavenormallydefinedtheCometd.org’sContinuationCometdServlet: <servlet> <servlet-name>cometd</servlet-name>

<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class> <init-param> <param-name>filters</param-name> <param-value>/WEB-INF/filters.json</param-value> </init-param> …. <load-on-startup>1</load-on-startup> </servlet>

Youcandownloadfromatmosphere.dev.java.nettheCometd.orgsamples.

Page 33: Atmosphere Whitepaper

AtmosphereFramework‐WhitePaper 33

AnnexA‐WebServerdifferencesAlltheWebServersaren’tsupportingthesamefunctionalitywhentheirnativeCometAPIisused.Belowisatableexplainingwhosupportwhat.

Jetty Tomcat GlassFish WebLogic JBossWeb

Optionalatmosphere.xml X X X X

Optionalweb.xmlinit‐param

com.sun.jersey.config.property.packages

X X X X

Auto‐detectclientremotedisconnection

(clientdisconnect)

X(*) X X

(*)YoumustconfiguretheCometConnectionManagerValveValve

TheServlet3.0CometSupportSPIsupportsalltheabove,andtheBlockingI/OCometSupportSPIsupportsallexcepttheclientdisconnect.