Building WebSocket and Server Side Events Applications using Atmosphere

Post on 10-May-2015

4,588 views 5 download

Tags:

description

An introduction to WebSocket and Server Side Events using the Atmosphee Framework

transcript

Building WebSocket and Server Side Events application using Atmosphere

Jeanfrancois Arcand

twitter.com/jfarcand facebook.com/jeanfrancois.arcand.3

Who I am?

Author of Atmosphere

Author of AHC HTTP/WebSocket

library

Author of Grizzly Framework

10 years @ Sun

Microsystems

Author of GlassFish Micro

Kernel

Atmosphere

Apache 2 Github ~900 « followers »

60 000 unique download per

months

Client + serverSupported

by25 frameworks Scala,

Groovy, JRuby, Java

1.0.9 / 1.1.beta2

Depuis 2008

Atmosphere

Apache 2 Github ~900 « followers »

60 000 unique download per

months

Client + serverSupported

by25 frameworks Scala,

Groovy, JRuby, Java

1.0.9 / 1.1.beta2

Depuis 2008

~1000 followers on Twitter

~400 users

mailing list

WebSocket: A Socket, that’s it!

WebSockets

Conclusion

WebSocket is a web technology providing full-duplex communications channels over a single TCP connection. The WebSocket API is being standardized by the W3C, and the WebSocket protocol has been standardized by the IETF as RFC 6455.

WebSockets

WARNING!!Nobody is/will/was fired

because of long-polling!!!

Browser Serverrequest

empty response

request

response

event

request

request

responseevent

request

response part

event

response part

event

Polling Long Polling Streaming

Browser Server

Browser Server

request

responseevent

event

request

Response

event

response

event

Browser Server

WebSocket =>

WebSockets

HTML5

Bi-directional

WebSockets

HTML5

Proxy/Firewall

Bi-directional

WebSockets

HTML5

Proxy/Firewall

Bi-directional

« Less network overhead »

WebSockets

HTML5

Proxy/Firewall

Bi-directional

« Less network overhead »

Faster

WebSockets

HTML5

Proxy/Firewall

Bi-directional

« Less network overhead »

Faster than Ajax

SubProtocol

WebSockets

Real time apps

Collaboration

Presence

Notification

Anything!

T 127.0.0.1:65062 -> 127.0.0.1:8080 [AP]

GET / HTTP/1.1.

Upgrade: websocket.

Connection: Upgrade.

Host: 127.0.0.1:8080.

Origin: http://127.0.0.1:8080.

Sec-WebSocket-Key: Tz9qdt3lmte6Slf+GvpRqQ==.

Sec-WebSocket-Version: 13.

Sec-WebSocket-Extensions: x-webkit-deflate-frame.

First request

T 127.0.0.1:8080 -> 127.0.0.1:51292 [AP]

HTTP/1.1 101 Switching Protocols.

Upgrade: WebSocket.

Connection: Upgrade.

Sec-WebSocket-Accept: HVXA7SqH5uYeN6aD9tZ0JQbfTJA=.

Second Request

T 127.0.0.1:8080 -> 127.0.0.1:51292 [AP]

HTTP/1.1 101 Switching Protocols.

Upgrade: WebSocket.

Connection: Upgrade.

Sec-WebSocket-Accept: HVXA7SqH5uYeN6aD9tZ0JQbfTJA=.

Life if good!

T 127.0.0.1:8080 -> 127.0.0.1:65064 [AP]

HTTP/1.1 501 Not Implemented.

Server: Apache-Coyote/1.1.

X-Atmosphere-error: Websocket protocol not supported.

Transfer-Encoding: chunked.

Date: Fri, 15 Jun 2012 10:06:30 GMT.

Connection: close.

.

OUPS!!!

T 127.0.0.1:8080 -> 127.0.0.1:65064 [AP]

HTTP/1.1 501 Not Implemented.

Server: Apache-Coyote/1.1.

X-Atmosphere-error: Websocket protocol not supported.

Transfer-Encoding: chunked.

Date: Fri, 15 Jun 2012 10:06:30 GMT.

Connection: close.

.

OUPS!!!

Atmosphere to the rescue

WebSocket API – Standard JavaScript

websocket = new WebSocket(wsUri);

websocket.onopen = function(evt) { …};

websocket.onclose = function(evt) { …};

websocket.onmessage = function(evt) { …};

websocket.onerror = function(evt) { …};

webSocket.send(…)

Server – No Standard yet

•Node.js

•Pusher

•Jetty

•GlassFish

•Tomcat

•Apache

•NIO Framework like Netty and Grizzly

WebSocket API – Java

Jetty 7, GlassFish 3.1, Netty 3, Tomcat 7.0.27, Resin 4, JBoss 7

JSR 356: http://jcp.org/en/jsr/detail?id=356

AHC (Client -> De facto)

http://github.com/sonatype/async-http-client

WebSocket API – Java & Scala

wAsync:

https://github.com/Atmosphere/wasync

SwaggerSocket (REST over WebSocket)

https://github.com/wordnik/swaggersocket

WARNING! Y’en aura pas de facile!!!

Before (Long-Polling)

Browser

Server

Request

Before (Long-Polling)

Browser

Request

Server

Before (Long-Polling)

Browser

Request

Response

Server

Oups!!

Browser

Serverzzzz

Request

Oups!

Browser

Request

Server

Zzzz

Better!

Browser

Server

Cache

Request

Better!

Request

Server

Cache

Response

Browser

Pushing the limits (HTTP Streaming)

Browser

Server

Request

Pushing the limits (HTTP Streaming)

Browser

Request

Server

Pushing the limits (HTTP Streaming)

Browser

Request

Response

Server

Pushing the limits (HTTP Streaming)

Browser

Request

Response

Response

Server

Oups!!

Browser

Request

Response

Response

Server

JS HELL

Pushing the limits (HTTP Streaming)

Browser

Request

Response

Response

Server

L’enfer

Hack

Oups!!!

Browser

Request

Response

Response

Server

Proxy

Better

Browser

Request

Response

Response

Server

Cache

Better

Browser

Request

Response

Response

Server

Cache« HeartBea

t »

Better: Server Side Events (SSE)

Browser

Request

Response

Response

Server

Oups!!!

Browser

Request

Response

Response

Server

Proxy

Better

Browser

Request

Response

Response

Server

Cache« HeartBea

t »

Better

Browser

Request

Response

Response

Server

Cache« HeartBea

t »

Not Supported by

Internet Explorer

WebSockets

Browser

Server

Hanshake

WebSockets

Browser

Server

Hanshake

OK

WebSockets

Browser

Server

Request

WebSockets

Browser

Request

Server

WebSockets

Browser

Server

Response

WebSockets

Browser

Server

Request

WebSockets

Browser

Server

Request

Request

WebSockets

Browser

Request

Request

Server

WebSockets

Browser

Server

Response

Response

Anytime

Browser

Response

Server

Ah la belle vie, la vie, la vie ahah!

Browser

Response

Server

Oups!!

Browser

Response

ServerProx

y

Better!

Browser

Response

Server

Cache

Better!

Browser

Response

Server

Cache« HeartBea

t »

Ah la belle vie, la vie, la vie, ahah

OUPS!!!

Go!!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

HELP

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Au Secour

s!!

Streaming

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Au Secour

s!!

Streaming

SSE

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Au Secour

s!!

Streaming

SSE

JSONP

Free for all!

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Au Secour

s!!

Streaming

SSE

Long Polling

JSONP

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

Atmosphere to the

rescue!!!

Atmosphere -WebSockets

Tomcat7

Jetty7

Jetty8

GlassFish3.

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

atm

osp

here

.js

Atm

osp

here

API

Atmosphere - HTML5 Server Side Events

Tomcat7

Jetty7

Servlet3

WebLogic

GlassFish

312

Firefox

Safari

Opera

Chrome

IE

atm

osp

here

.js

Atm

osp

here

API

Atmosphere Long-Polling/HTTP Streaming

JBoss

Jetty7

Servlet3

WebLogic.

GlassFish

Firefox

Safari

Opera

Chrome

IE

atm

osp

here

.js

Atm

osp

here

API

Atmosphere

JBoss

Jetty7

Servlet3

WebLogic.

GlassFish

Firefox

Safari

Opera

Chrome

IE

atm

osp

here

.js

Atm

osp

here

API

One API to rule them

all

Socket.IO, GWT, Wicket, JSF, etc.

JBoss

Jetty7

Servlet3

WebLogic.

GlassFish

Firefox

Safari

Opera

Chrome

IE

Sock

et.

IO

Atm

osp

here

API

PORTABLE!!!!!

JBoss

Jetty7

Servlet3

WebLogic.

GlassFish

Firefox

Safari

Opera

Chrome

IE

Sock

et.

IO

Atm

osp

here

API

PORTABLE

•There are still a lot of dinosaur in the wilderness!

Deploy in Production

impossible

Big Mistake!!!!!

Demo

public interface AtmosphereHandler {

void onRequest(AtmosphereResource resource)

throws IOException;

void onStateChange(AtmosphereResourceEvent

event) throws IOException;

void destroy();

}

AtmosphereHandler

public class ChatAtmosphereHandler implements AtmosphereHandler {

@Override

public void onRequest(AtmosphereResource r) throws IOException {

AtmosphereRequest req = r.getRequest();

if (req.getMethod().equalsIgnoreCase("GET")) {

r.suspend();

} else if (req.getMethod().equalsIgnoreCase("POST")) {

r.getBroadcaster().broadcast(req.getReader().readLine().trim());

}

}

AtmosphereHandler

public void onStateChange(AtmosphereResourceEvent event) throws IOException {

….

if (event.isSuspended()) {

res.getWriter().write(new Data(author, message).toString());

switch (r.transport()) {

case JSONP:

case AJAX:

case LONG_POLLING:

event.getResource().resume();

break;

case WEBSOCKET :

case STREAMING:

res.getWriter().flush();

break;

}

} else if (!event.isResuming()){

event.broadcaster().broadcast(new Data("Someone", "say bye bye!").toString());

}

}

AtmosphereHandler

@AtmosphereHandlerService(

path="/chat",

interceptors = {AtmosphereResourceLifecycleInterceptor.class,

BroadcastOnPostAtmosphereInterceptor.class})

public class ChatRoom extends OnMessage<String> {

private final ObjectMapper mapper = new ObjectMapper();

@Override

public void onMessage(AtmosphereResponse response, String message) {

response.getWriter()

.write(mapper.writeValueAsString(

mapper.readValue(message, Data.class)));

}

}

OnMessage

@ManagedAtmosphereHandlerService (path = "/chat")

public class ChatAtmosphereHandler {

private final ObjectMapper mapper =

new ObjectMapper();

@Message

public void onMessage(AtmosphereResponse response,

String message) throws IOException {

response.getWriter().write(

mapper.writeValueAsString(

mapper.readValue(message, Data.class)));

}

@Managed

@AtmosphereHandlerService(

path = "/chat",

broadcasterCache =

HeaderBroadcasterCache.class,

interceptors = {

AtmosphereResourceLifecycleInterceptor.class,

BroadcastOnPostAtmosphereInterceptor.class,

TrackMessageSizeInterceptor.class,

HeartbeatInterceptor.class})

@Managed are..

@Path("/")

public class ChatResource {

@Suspend(contentType = "application/json")

@GET

public String suspend() {

return "";

}

@Broadcast(writeEntity = false)

@POST

@Produces("application/json")

public Response broadcast(Message message) {

return new Response(message.author, message.message);

}

}

Jersey

var socket = $.atmosphere;

var subSocket;

var transport = 'websocket';

var request = { url: document.location.toString() + 'chat',

contentType : "application/json",

logLevel : 'debug',

shared : true,

transport : transport ,

trackMessageLength : true,

fallbackTransport: 'long-polling'};

Client

request.onOpen = function(response) {

};

request.onTransportFailure = function(errorMsg, request) {

};

request.onReconnect = function (request, response) {

};

request.onMessage = function (response) {

};

request.onClose = function(response) {

}

request.onError = function(response) {

};

subSocket = socket.subscribe(request);

Client

subSocket.push(….);

Client

•Default: in-memory

•Cloud

• RedisBroadcaster

• JMSBroadcaster

• XMPPBroadcaster

• HazelcastBroadcaster

• JGroupsBroascaster

•Multi-Threads, Async I/O par default

Broadcaster

Broadcaster

•WebSocketHandler

• Only WebSocket (WARNING)!

•AtmosphereHandler

• All transports

•Jersey Resource

• All transports

•Meteor

• All transports

Atmosphere Components

Démo

•WebSocketProtocolDefine your own protocol on top of WebSocket

•Default:WebSocket message => POST

•SwaggerSocket: REST over WebSockets -> More information

WebSocket Sub Protocol

PLEASE HELPhttp://github.com/Atmosphere/atmosp

here

twitter.com/jfarcandtwitter.com/atmo_frameworktwitter.com/swaggersocket

http://github.com/Atmosphere/

http://github.com/wordnik/swaggersocket