Upload
jfarcand
View
4.587
Download
5
Tags:
Embed Size (px)
DESCRIPTION
An introduction to WebSocket and Server Side Events using the Atmosphee Framework
Citation preview
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