SlideShare a Scribd company logo
WebSockets on the JVM: 
Atmosphere to the rescue! 
@jfarcand 
Async-IO.org, http://async-io.org 
CTO 
@atmo_framework @jfarcand
WebSockets: Myth or Reality 
WebSocket a standard? Really? 
Tricks for Production Ready 
WebSocket Application 
@atmo_framework @asyncio
WebSockets 
is a web technology providing for bi-directional, 
full-duplex communications channels 
over a single TCP connection. 
Polling Long Polling Streaming 
Browser Server 
request 
empty response 
request 
response 
event 
Browser Server Browser Server 
request 
response 
request 
event 
request 
response part 
event 
response part 
event 
response 
request 
event 
event 
WebSocket 
Browser Server 
request 
Response 
event 
response 
event 
@atmo_framework @asyncio
Agenda 
•Who I am 
•Atmosphere 
•WebSockets: Serveur Side 
•WebSocket: Client Side 
•Socket.IO and Socks.js 
•Conclusion 
@atmo_framework @asyncio
Who is this strange accent guy 
• Creator of Frameworks 
• Grizzly (NIO Framework) 
• AsyncHttpClient 
(HTTP/WebSocket) 
• Atmosphere Framework 
• Ex-GlassFish, Tomcat & Jetty 
« committer » 
• Ex Sun Microsystem, France 
Telecom, Ning, Sonatype 
@atmo_framework @asyncio
Currently 
•Founder anf CTO Async- 
IO.org 
•Since 2013 
•Atmosphere Support, 
Atmosphere Pro & Elite 
•Atmosphere is still licenced 
Apache 2 
@atmo_framework @asyncio
Async-IO 
@atmo_framework @asyncio
WebSockets: Server Side 
blank slide 
for your own 
pictures
WebSockets: Server Side 
•Tomcat 7+, Jetty 7+, GlassFish 3+, Resin 2+, JBoss 
7.1.2+ native Websocket API 
•Non Portable, Unstable API 
•Missing Functionality 
•What the point of Atmosphere then??????? 
@atmo_framework @asyncio
blank slide 
for your own 
pictures
WebSockets: Server Side 
Atmosphere 
To 
The 
Rescue! 
@atmo_framework @asyncio
Atmosphere: 
github.com/Atmosphere 
•Portable, Stable, EVERYWHERE 
•Use Native API or JSR 356 
•Javascript API(s) & Java (wAsync) 
•950+ mailing list 
@atmo_framework @asyncio
JAX Awards 2014 
Nominated for Most 
Innovative Java 
Technology 
@atmo_framework @asyncio
Atmosphere: Well Established!! 
http://www.parleys.c 
om/play/514892260 
364bc17fc56bde7/c 
hapter0/about 
@atmo_framework @asyncio
Atmosphere: Run on top of 
@atmo_framework @asyncio
atmosphere.js 
•100% Javascript Library 
•Small, portable, mobile optimized 
•Transparent Fallback 
•One API to Rule them all: WebSockets/Server Sides 
Event/Long-Polling/HTML File/JSONP/Polling/Streaming 
etc. 
@atmo_framework @asyncio
Atmosphere : Clients 
@atmo_framework @asyncio
Atmosphere: Browsers 
6+ 
3.5+ 
4+ 
3+ 
10+ 
@atmo_framework @asyncio
Atmosphere: Into the Cloud 
•Your Atmosphere’s Application transparently work into 
the cloud 
Proxy/Load 
balancer 
@atmo_framework @asyncio
Atmosphere: Cloud 
@atmo_framework @asyncio
blank slide 
for your own 
pictures 
Enterprise 
Ready?
Atmosphere Pro! 
• atmosphere-satellite: replicate your data and code together In-Memory for 
faster execution and seamless elastic scalability across your 
Atmosphere's Nodes/Servers. 
• atmosphere-tower-control: Monitor your Atmosphere's Node/Server state 
via any JMX compliant tool like Java Mission Control. Get statistics on 
how many websocket or long-polling clients are currently connected, 
add/move connected clients from one node to another, for example in 
case of a node being restarted, etc. 
• atmosphere-postman: Client/Server extension to Atmosphere to support 
message delivery guarantee. 
http://async-io.org/AtmospherePro.html 
@atmo_framework @asyncio
Fix broken 
browsers/s 
ervers for 
you! ` 
blank slide 
for your own 
pictures
Atmosphere
Atmosphere 
var socket = atmosphere; 
var subSocket; 
var request = { url: document.location.toString() + 'chat’, contentType : "application/json”, transport : "websocket" , trackMessageLength : 
true }; 
request.onOpen = function(response) { 
content.html($('<p>', { text: 'Atmosphere connected using ' + response.transport })); 
}; 
request.onMessage = function (response) { 
var json = atmosphere.util.parseJSON(response.responseBody) 
… 
}; 
request.onClose = function(response) {…}; 
request.onReopen = function(response) {….} 
request.onTransportFailure = function(errorMsg, request) {…} 
subSocket = socket.subscribe(request);
@ManagedService(path = "/chat”) 
public class Chat { 
@Ready 
public void onReady(AtmosphereResource r) {..} 
@Disconnect 
public void onDisconnect(AtmosphereResourceEvent e) {..} 
@Message( encoders = {JacksonEncoder.class}, 
decoders = {JacksonDecoder.class}) 
public Reply onMessage(Message message){ 
return handleAndReply(message); 
} 
} 
Atmosphere
Problem #1 – Fallback 
•Browser 
• Old version 
• No support (IE 9) 
•Proxys 
• Disconnect, block 
•Load Balancer 
• Breaks Session Affinity 
@atmo_framework @asyncio
Fallback with Atmosphere 
public void onReady(AtmosphereResource r) { 
switch (r.transport()) { 
case WEBSOCKET: 
case SSE: 
case LONG-POLLING: 
case STREAMING: 
case JSONP: 
case POLLING: 
r.write(“Atmosphere is cool”); 
} 
} 
@atmo_framework @asyncio
Atmosphere I/O 
•WebSocket uses « non blocking I/O » 
•Fallback simulates « non blocking I/O> 
Browsers behave the same way as packet are delivered 
uniformely. 
@atmo_framework @asyncio
Problem #2 –Protocol 
Tomcat 7.x/8.x => RFC 
6455 (Version 13) !!<= 
Safari 5.0.x 
Jetty9.1+ => Hixie 76 
<= Safari 5.0.x 
@atmo_framework @asyncio
Protocol Version 
•Atmosphere => Transparent Fallback in case the 
protocol is not supported 
@atmo_framework @asyncio
Problem #3 – Lost Lost Lost 
• I/O error, websocket message 
will be lost. 
• Message must be put inside a 
cache 
• Message must be discarted if 
the connection never come 
back. 
@atmo_framework @asyncio
Atmosphere – Messages Lost 
@ManagedService(path = "/chat”) 
public class Chat { 
@Message 
public void onMessage(AtmosphereResource r, String message){ 
// Transparently cache the message in case of a problem 
// Transparently write it back once reconnected 
r.write(message); 
} 
} 
@atmo_framework @asyncio
Problem #4 – Proxy 
• Existing Proxy are cutting the 
connection. 
• Must recover transparently 
from a disconnect. 
• Heartbeat saves your day! 
@atmo_framework @asyncio
Atmosphere – Proxy ? No Problem! 
@atmo_framework @asyncio
Problem #5 – New Spec! 
• Difference between Tomcat, 
Undertow and Jetty already! 
• Spec is young, missing fondamental 
concepts. 
• Tomcat 8.0.12 is stable. GlassFish 4 
is dead, Jetty 9.1.3 stable, 
Undertow 1.1.Final is stable, 
WelLogic is broken. 
@atmo_framework @asyncio
Problem #5 – JSR 356: Tomcat vs 
Jetty 
@Message 
public void onMessage(String m, Session s) { 
for (Session s: sessions.getOpenSessions()){ 
// Tomcat will throw an IllegalStateException 
// if more than one thread call sendXXX. 
// Jetty won’t! 
session.getAsyncRemote().sendText(m); 
} 
} 
@atmo_framework @asyncio
Problem #5 – JSR 356: Tomcat vs 
Jetty 
private final Semaphore semaphore = new Semaphore(1, true); 
@Message 
public void onMessage(String m, Session s) { 
for (Session s: sessions.getOpenSessions()){ 
try{ 
semaphore.acquireUninterruptibly(); 
session.getAsyncRemote().sendText(m, …); 
}finally { 
semaphore.release(); 
} 
} 
} 
@atmo_framework @asyncio
Problem #5 – Tomcat vs Jetty 
• I/O Event aren’t delivered the same 
way. 
• CloseReason not the same depending 
on the server!!!! 
// Hack 
if (closeCode == 1000 && getContainerName().contains("Tomcat")) { 
closeCode = 1005; 
} 
@atmo_framework @asyncio
Firefox is the new Internet Explorer 
6! 
// Reload a tab/window 
// Firefox => 1001 
// Chrome => 1000 
if (isFirefox && c.getCode() == CloseReason.GOING_AWAY 
|| c.getCode() == CloseReason.NO_STATUS_CODE) { 
... 
} 
@atmo_framework @asyncio
Firefox is the new Internet Explorer 
6! 
Reload in Firefox produces phantom 
websockets connections!!!!!!! 
@atmo_framework @asyncio
Problem #6 – Closing Code 
• How to detect if a 
websocket was closed by a 
Proxy, a Load Balancer or 
the Browser!! 
@atmo_framework @asyncio
Hell exists!! 
@atmo_framework @asyncio
Atmosphere 
@Disconnect 
public void onClose(AtmosphereResourceEvent e) { 
if (e.isClosedByClient()){ 
} else if (e.isClosedByApplication()) { 
} else if (e.isUnexpectlyClosed()) { 
} 
@atmo_framework @asyncio
WebSockets: Client Side 
blank slide 
for your own 
pictures 
@atmo_framework @asyncio
WebSockets: Javascript API 
W•ebWSo3cCk eStpewcsifi=ca tnieown WebSocket(“ws://127.0.0.1:8080”); 
ws.onopen = function (message) { 
}; 
ws.onclose = function (message) { 
}; 
ws.onmessage = function (message) { 
} 
@atmo_framework @asyncio
WebSocket: Supported Browsers 
10+ 
10+ 
6+ 
5+ 
10+ 
? 
2+ 
@atmo_framework @asyncio
W3C API 
Ohhhhhhhhh 
•Pong/Ping: No exposed 
•Headers: Can’t add/read 
•Query String: No API, append them to the url 
•Cookie: Impossible to read them 
@atmo_framework @asyncio
Atmosphere: First request 
•W3C Specification T 127.0.0.1:52212 -> 127.0.0.1:8080 [AP] 
GET /chat?X-Atmosphere-tracking-id=0&X-Atmosphere- 
Framework=2.2.0-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere- 
TrackMessageSize=true&X-Cache-Date=0&Content- 
Type=application/json&X-atmo-protocol=true HTTP/1.1. 
Upgrade: websocket. 
Connection: Upgrade. 
Host: 127.0.0.1:8080. 
Origin: http://127.0.0.1:8080. 
Sec-WebSocket-Key: TCBKrAyFFwW8HUXqLpj2wg==. 
Sec-WebSocket-Version: 13. 
Sec-WebSocket-Extensions: permessage-deflate; 
client_max_window_bits, x-webkit-deflate-frame. 
@atmo_framework @asyncio
Atmosphere: First request 
•W3C Specification 
T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] 
HTTP/1.1 101 Switching Protocols. 
X-Atmosphere-first-request: true. 
X-Atmosphere-tracking-id: bb7aeeb7-9e44-4aa9-848d-14bba6532de9. 
Connection: Upgrade. 
Sec-WebSocket-Accept: 5mHABDQFkWBtjoinv3lj+6dVwHg=. 
Upgrade: WebSocket. 
@atmo_framework @asyncio
Problem #1 – onclose 
• Firefox will execute the 
ws.onclose function on F5 
(reload) 
• Chrome/Safari ….. NOT! 
@atmo_framework @asyncio
Problem #1: onclose 
•W3C Specification 
ws.onclose = function(closeReason) { 
switch(closeReason.code) { 
case 1000: 
…. 
} 
// Firefox will execute this logic on every reload 
// closeReason.wasClean unreliable 
if (dirtyClose) { 
reconnectTo(…); 
} 
} 
@atmo_framework @asyncio
Atmosphere: onclose 
•W3C Specification 
// Hahahaha go to hell Firefox!! 
atmosphere.onClose = function (callback) { 
}; 
@atmo_framework @asyncio
Problem #2 – Messages’ length 
• Messages can be truncated 
when the server write 
them 
• The Browser received 
them in two chunks or I/O 
operation 
@atmo_framework @asyncio
Problem #2: Messages’ length 
•W3C Specification 
// Craaaaaaashhhhhhhhhhhhh 
ws.onmessage = function (callback) { 
window.JSON.parse(callback.data); 
}; 
@atmo_framework @asyncio
Problem #2: What’s Up, Doctor! 
•W3C Specification 
// atmosphere.js transparently 
// handles it 
atmosphere.onMessage = function (callback) { 
window.JSON.parse(callback.responseBody); 
}; 
@atmo_framework @asyncio
Problem #3 – UUID and Cookie 
• No Cookie to identify 
the client 
@atmo_framework @asyncio
Problem #3 – UUID and Cookie 
• Solutions: 
• Normal request => set-cookie 
• Next WebSockets 
• Useful if you deploy on 
Amazon 
(1) HTTP 
(2) websockets 
@atmo_framework @asyncio
Atmosphere: Handshake Protocol 
•W3C Specification 
T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] 
.651|bb7aeeb7-9e44-4aa9-848d-14bba6532de9|1397426374301| 
T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] 
.. 
T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] 
.. 
@atmo_framework @asyncio
Problem #4 – Proxy 
• Proxy can close the websocket or 
completely ignore the websocket 
handshake, completely fooling the 
server…and the browser! 
• ws.open never called!!!! 
@atmo_framework @asyncio
Problem #4 – Proxy 
•W3C Specification 
websocket.onopen = function (message) { 
alert(“Ha ha ha good luck!!!”); 
} 
websocket.onmessage = function(message) { 
// Never called 
alert(“Sleep on it!!!”); 
} 
@atmo_framework @asyncio
Problem #4 – Proxy 
•W3C Specification 
atmosphere.onReopen = function (callback) { 
// Yeahhhh!!! 
}; 
atmosphere.onTransportFailure = function (callback) { 
// Apache Proxy, I hate you!!! 
}; 
@atmo_framework @asyncio
Hazelcast 
@atmo_framework @asyncio
Socket.IO and Socks.js 
SockJs et Socket.io 
blank slide 
for your own 
pictures 
@atmo_framework @asyncio
Socket.IO 
• For Node.js 
• Streaming, Long-Polling and now Websocket 
• Extremely popular, lot of »issues » 
602 => https://github.com/LearnBoost/socket.io/issues 
• Supported by Atmosphere, both client and server side. Replace 
node.js 
@atmo_framework @asyncio
Socket.IO - Atmosphere 
@•ManWag3eCdS Serpveiccief(ipcaatthi o=n "/chat”) 
public class Chat { 
@Ready 
public void onReady(AtmosphereResource r) {..} 
@Disconnect 
public void onDisconnect(AtmosphereResourceEvent e) {..} 
@Message( encoders = {JacksonEncoder.class}, 
decoders = {JacksonDecoder.class}) 
public Reply onMessage(Message message){ 
return handleAndReply(message); 
} 
} 
@atmo_framework @asyncio
Socket.IO - Atmosphere 
•W3C Specification 
var socket = io.connect('', {'resource’:document.location.toString() + 'chat'}); 
socket.on('connect', function () { 
content.html($('<p>', 
{ text:'Atmosphere connected using this.socket.transport.name})); 
}); 
socket.on('chat message', function() { 
var json = jQuery.parseJSON(msg); 
… 
} 
); 
socket.on(‘error’, function (e) {…}); 
@atmo_framework @asyncio
Socks.js 
•For Node.js 
•Emulate WebSocket, with « fallback » 
•Socks.js popularity increase, due to Spring 4, Vert.x 
and Atmosphere support 
@atmo_framework @asyncio
Socks.js - Atmosphere 
@•ManWag3eCdS Serpveiccief(ipcaatthi o=n "/clavarder”) 
public class Chat { 
@Ready 
public void onReady(AtmosphereResource r) {..} 
@Disconnect 
public void onDisconnect(AtmosphereResourceEvent e) {..} 
@Message( encoders = {JacksonEncoder.class}, 
decoders = {JacksonDecoder.class}) 
public Reply onMessage(Message message){ 
return handleAndReply(message); 
} 
} 
@atmo_framework @asyncio
Socks.js- Atmosphere 
•W3C Specification 
var socket = new SockJS('http://' + window.location.host + '/chat', null, { 
'protocols_whitelist': ['websocket', 'xhr-streaming', 
'iframe-eventsource', 'iframe-htmlfile', 
'xhr-polling', 'jsonp-polling'] }); 
socket.onopen = function() { 
content.html($('<p>', { text: 'Atmosphere connected using SockJs client'})); 
} 
socket.onmessage = function (response) { 
var message = response.data; 
var json = JSON.parse(message); 
} 
socket.onclose = function() { 
} 
@atmo_framework @asyncio
Conclusion 
•WebSockets in Prod without fallback? You’re Crazy!! 
•Atmosphere is production ready, and fixes all the 
issues listed here! 
•What are you waiting for? 
@atmo_framework @asyncio
@All images copyright JeanFrancois Arcand 
Credits 
https://www.linkedin.com/in/jfarcand 
http://async-io.org 
http://github.com/Atmosphere/atmosphere 
http://github.com/jfarcand 
@atmo_framework @asyncio

More Related Content

PPT
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
PPTX
The Atmosphere Framework
PPTX
Building WebSocket and Server Side Events Applications using Atmosphere
PPTX
Reverse ajax in 2014
PPTX
Writing Portable WebSockets in Java
PPTX
Asynchronous Web Programming with HTML5 WebSockets and Java
PPTX
Web sockets in Java
PDF
WebSockets with Spring 4
Writing highly scalable WebSocket using the Atmosphere Framework and Scala
The Atmosphere Framework
Building WebSocket and Server Side Events Applications using Atmosphere
Reverse ajax in 2014
Writing Portable WebSockets in Java
Asynchronous Web Programming with HTML5 WebSockets and Java
Web sockets in Java
WebSockets with Spring 4

What's hot (20)

PDF
Building Next Generation Real-Time Web Applications using Websockets
PDF
WebSockets wiith Scala and Play! Framework
PPTX
0-60 with Goliath: Building High Performance Ruby Web-Services
PDF
Building Real-Time Applications with Android and WebSockets
PDF
GWT Web Socket and data serialization
PPT
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.com
PPTX
Spring Boot & WebSocket
PDF
Realtime web application with java
PDF
Using Websockets with Play!
KEY
Servers with Event Machine - David Troy - RailsConf 2011
PPTX
0-60 with Goliath: High performance web services
ODP
Implementing Comet using PHP
KEY
Speedy TDD with Rails
PPTX
Ruby Proxies for Scale, Performance, and Monitoring
PPTX
Websockets and SockJS, Real time chatting
PDF
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
PDF
Beyond Breakpoints: A Tour of Dynamic Analysis
PPTX
Large scale web socket system with AWS and Web socket
PPTX
Solving anything in VCL
PPTX
Building Next Generation Real-Time Web Applications using Websockets
WebSockets wiith Scala and Play! Framework
0-60 with Goliath: Building High Performance Ruby Web-Services
Building Real-Time Applications with Android and WebSockets
GWT Web Socket and data serialization
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.com
Spring Boot & WebSocket
Realtime web application with java
Using Websockets with Play!
Servers with Event Machine - David Troy - RailsConf 2011
0-60 with Goliath: High performance web services
Implementing Comet using PHP
Speedy TDD with Rails
Ruby Proxies for Scale, Performance, and Monitoring
Websockets and SockJS, Real time chatting
[1D1]신개념 N스크린 웹 앱 프레임워크 PARS
Beyond Breakpoints: A Tour of Dynamic Analysis
Large scale web socket system with AWS and Web socket
Solving anything in VCL

Viewers also liked (20)

PPTX
Html starting
PPT
HTML & CSS
PPT
Tomcat New Evolution
PDF
Introduction tomcat7 servlet3
PDF
Enterprise(d) Tomcat & httpd
PPTX
Ob1k presentation at Java.IL
PPTX
Asynchronous design with Spring and RTI: 1M events per second
PPTX
Fastest Servlets in the West
PPT
Multithreading, Blocking IO and Async IO
PPTX
PPTX
Html5 tutorial for beginners
PDF
Great Java Application Server Debate
PPT
Async IO and Multithreading explained
PPT
Knowledge Sharing : Java Servlet
PDF
Introduction to WebSockets
PPTX
Introduction to WebSockets
PPT
Auxiliary : Tomcat
PPT
Origins and evolution of HTML and XHTML
PPTX
Async servlets
PDF
Introduction to Apache Tomcat 7 Presentation
Html starting
HTML & CSS
Tomcat New Evolution
Introduction tomcat7 servlet3
Enterprise(d) Tomcat & httpd
Ob1k presentation at Java.IL
Asynchronous design with Spring and RTI: 1M events per second
Fastest Servlets in the West
Multithreading, Blocking IO and Async IO
Html5 tutorial for beginners
Great Java Application Server Debate
Async IO and Multithreading explained
Knowledge Sharing : Java Servlet
Introduction to WebSockets
Introduction to WebSockets
Auxiliary : Tomcat
Origins and evolution of HTML and XHTML
Async servlets
Introduction to Apache Tomcat 7 Presentation

Similar to Websockets on the JVM: Atmosphere to the rescue! (20)

PDF
Nodejs and WebSockets
PPT
Krug Fat Client
PDF
Time for Comet?
PDF
WebSocket Perspectives 2015 - Clouds, Streams, Microservices and WoT
PDF
Not Only Streams for Akademia JLabs
PDF
Going realtime with Socket.IO
PDF
WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
KEY
The HTML5 WebSocket API
PDF
Transforming WebSockets
PDF
Lecture 6 Web Sockets
PDF
Understanding the Rails web model and scalability options
PDF
Toster - Understanding the Rails Web Model and Scalability Options
PPTX
Event-driven IO server-side JavaScript environment based on V8 Engine
PPTX
Enhancing Mobile User Experience with WebSocket
PPTX
Hammock, a Good Place to Rest
PPTX
Messaging for Web and Mobile with Apache ActiveMQ
PDF
Play Framework: async I/O with Java and Scala
PDF
Going Live! with Comet
PPT
HTML5 WebSocket: The New Network Stack for the Web
KEY
Socket.io
Nodejs and WebSockets
Krug Fat Client
Time for Comet?
WebSocket Perspectives 2015 - Clouds, Streams, Microservices and WoT
Not Only Streams for Akademia JLabs
Going realtime with Socket.IO
WebSockets: The Current State of the Most Valuable HTML5 API for Java Developers
The HTML5 WebSocket API
Transforming WebSockets
Lecture 6 Web Sockets
Understanding the Rails web model and scalability options
Toster - Understanding the Rails Web Model and Scalability Options
Event-driven IO server-side JavaScript environment based on V8 Engine
Enhancing Mobile User Experience with WebSocket
Hammock, a Good Place to Rest
Messaging for Web and Mobile with Apache ActiveMQ
Play Framework: async I/O with Java and Scala
Going Live! with Comet
HTML5 WebSocket: The New Network Stack for the Web
Socket.io

Websockets on the JVM: Atmosphere to the rescue!

  • 1. WebSockets on the JVM: Atmosphere to the rescue! @jfarcand Async-IO.org, http://async-io.org CTO @atmo_framework @jfarcand
  • 2. WebSockets: Myth or Reality WebSocket a standard? Really? Tricks for Production Ready WebSocket Application @atmo_framework @asyncio
  • 3. WebSockets is a web technology providing for bi-directional, full-duplex communications channels over a single TCP connection. Polling Long Polling Streaming Browser Server request empty response request response event Browser Server Browser Server request response request event request response part event response part event response request event event WebSocket Browser Server request Response event response event @atmo_framework @asyncio
  • 4. Agenda •Who I am •Atmosphere •WebSockets: Serveur Side •WebSocket: Client Side •Socket.IO and Socks.js •Conclusion @atmo_framework @asyncio
  • 5. Who is this strange accent guy • Creator of Frameworks • Grizzly (NIO Framework) • AsyncHttpClient (HTTP/WebSocket) • Atmosphere Framework • Ex-GlassFish, Tomcat & Jetty « committer » • Ex Sun Microsystem, France Telecom, Ning, Sonatype @atmo_framework @asyncio
  • 6. Currently •Founder anf CTO Async- IO.org •Since 2013 •Atmosphere Support, Atmosphere Pro & Elite •Atmosphere is still licenced Apache 2 @atmo_framework @asyncio
  • 8. WebSockets: Server Side blank slide for your own pictures
  • 9. WebSockets: Server Side •Tomcat 7+, Jetty 7+, GlassFish 3+, Resin 2+, JBoss 7.1.2+ native Websocket API •Non Portable, Unstable API •Missing Functionality •What the point of Atmosphere then??????? @atmo_framework @asyncio
  • 10. blank slide for your own pictures
  • 11. WebSockets: Server Side Atmosphere To The Rescue! @atmo_framework @asyncio
  • 12. Atmosphere: github.com/Atmosphere •Portable, Stable, EVERYWHERE •Use Native API or JSR 356 •Javascript API(s) & Java (wAsync) •950+ mailing list @atmo_framework @asyncio
  • 13. JAX Awards 2014 Nominated for Most Innovative Java Technology @atmo_framework @asyncio
  • 14. Atmosphere: Well Established!! http://www.parleys.c om/play/514892260 364bc17fc56bde7/c hapter0/about @atmo_framework @asyncio
  • 15. Atmosphere: Run on top of @atmo_framework @asyncio
  • 16. atmosphere.js •100% Javascript Library •Small, portable, mobile optimized •Transparent Fallback •One API to Rule them all: WebSockets/Server Sides Event/Long-Polling/HTML File/JSONP/Polling/Streaming etc. @atmo_framework @asyncio
  • 17. Atmosphere : Clients @atmo_framework @asyncio
  • 18. Atmosphere: Browsers 6+ 3.5+ 4+ 3+ 10+ @atmo_framework @asyncio
  • 19. Atmosphere: Into the Cloud •Your Atmosphere’s Application transparently work into the cloud Proxy/Load balancer @atmo_framework @asyncio
  • 21. blank slide for your own pictures Enterprise Ready?
  • 22. Atmosphere Pro! • atmosphere-satellite: replicate your data and code together In-Memory for faster execution and seamless elastic scalability across your Atmosphere's Nodes/Servers. • atmosphere-tower-control: Monitor your Atmosphere's Node/Server state via any JMX compliant tool like Java Mission Control. Get statistics on how many websocket or long-polling clients are currently connected, add/move connected clients from one node to another, for example in case of a node being restarted, etc. • atmosphere-postman: Client/Server extension to Atmosphere to support message delivery guarantee. http://async-io.org/AtmospherePro.html @atmo_framework @asyncio
  • 23. Fix broken browsers/s ervers for you! ` blank slide for your own pictures
  • 25. Atmosphere var socket = atmosphere; var subSocket; var request = { url: document.location.toString() + 'chat’, contentType : "application/json”, transport : "websocket" , trackMessageLength : true }; request.onOpen = function(response) { content.html($('<p>', { text: 'Atmosphere connected using ' + response.transport })); }; request.onMessage = function (response) { var json = atmosphere.util.parseJSON(response.responseBody) … }; request.onClose = function(response) {…}; request.onReopen = function(response) {….} request.onTransportFailure = function(errorMsg, request) {…} subSocket = socket.subscribe(request);
  • 26. @ManagedService(path = "/chat”) public class Chat { @Ready public void onReady(AtmosphereResource r) {..} @Disconnect public void onDisconnect(AtmosphereResourceEvent e) {..} @Message( encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class}) public Reply onMessage(Message message){ return handleAndReply(message); } } Atmosphere
  • 27. Problem #1 – Fallback •Browser • Old version • No support (IE 9) •Proxys • Disconnect, block •Load Balancer • Breaks Session Affinity @atmo_framework @asyncio
  • 28. Fallback with Atmosphere public void onReady(AtmosphereResource r) { switch (r.transport()) { case WEBSOCKET: case SSE: case LONG-POLLING: case STREAMING: case JSONP: case POLLING: r.write(“Atmosphere is cool”); } } @atmo_framework @asyncio
  • 29. Atmosphere I/O •WebSocket uses « non blocking I/O » •Fallback simulates « non blocking I/O> Browsers behave the same way as packet are delivered uniformely. @atmo_framework @asyncio
  • 30. Problem #2 –Protocol Tomcat 7.x/8.x => RFC 6455 (Version 13) !!<= Safari 5.0.x Jetty9.1+ => Hixie 76 <= Safari 5.0.x @atmo_framework @asyncio
  • 31. Protocol Version •Atmosphere => Transparent Fallback in case the protocol is not supported @atmo_framework @asyncio
  • 32. Problem #3 – Lost Lost Lost • I/O error, websocket message will be lost. • Message must be put inside a cache • Message must be discarted if the connection never come back. @atmo_framework @asyncio
  • 33. Atmosphere – Messages Lost @ManagedService(path = "/chat”) public class Chat { @Message public void onMessage(AtmosphereResource r, String message){ // Transparently cache the message in case of a problem // Transparently write it back once reconnected r.write(message); } } @atmo_framework @asyncio
  • 34. Problem #4 – Proxy • Existing Proxy are cutting the connection. • Must recover transparently from a disconnect. • Heartbeat saves your day! @atmo_framework @asyncio
  • 35. Atmosphere – Proxy ? No Problem! @atmo_framework @asyncio
  • 36. Problem #5 – New Spec! • Difference between Tomcat, Undertow and Jetty already! • Spec is young, missing fondamental concepts. • Tomcat 8.0.12 is stable. GlassFish 4 is dead, Jetty 9.1.3 stable, Undertow 1.1.Final is stable, WelLogic is broken. @atmo_framework @asyncio
  • 37. Problem #5 – JSR 356: Tomcat vs Jetty @Message public void onMessage(String m, Session s) { for (Session s: sessions.getOpenSessions()){ // Tomcat will throw an IllegalStateException // if more than one thread call sendXXX. // Jetty won’t! session.getAsyncRemote().sendText(m); } } @atmo_framework @asyncio
  • 38. Problem #5 – JSR 356: Tomcat vs Jetty private final Semaphore semaphore = new Semaphore(1, true); @Message public void onMessage(String m, Session s) { for (Session s: sessions.getOpenSessions()){ try{ semaphore.acquireUninterruptibly(); session.getAsyncRemote().sendText(m, …); }finally { semaphore.release(); } } } @atmo_framework @asyncio
  • 39. Problem #5 – Tomcat vs Jetty • I/O Event aren’t delivered the same way. • CloseReason not the same depending on the server!!!! // Hack if (closeCode == 1000 && getContainerName().contains("Tomcat")) { closeCode = 1005; } @atmo_framework @asyncio
  • 40. Firefox is the new Internet Explorer 6! // Reload a tab/window // Firefox => 1001 // Chrome => 1000 if (isFirefox && c.getCode() == CloseReason.GOING_AWAY || c.getCode() == CloseReason.NO_STATUS_CODE) { ... } @atmo_framework @asyncio
  • 41. Firefox is the new Internet Explorer 6! Reload in Firefox produces phantom websockets connections!!!!!!! @atmo_framework @asyncio
  • 42. Problem #6 – Closing Code • How to detect if a websocket was closed by a Proxy, a Load Balancer or the Browser!! @atmo_framework @asyncio
  • 44. Atmosphere @Disconnect public void onClose(AtmosphereResourceEvent e) { if (e.isClosedByClient()){ } else if (e.isClosedByApplication()) { } else if (e.isUnexpectlyClosed()) { } @atmo_framework @asyncio
  • 45. WebSockets: Client Side blank slide for your own pictures @atmo_framework @asyncio
  • 46. WebSockets: Javascript API W•ebWSo3cCk eStpewcsifi=ca tnieown WebSocket(“ws://127.0.0.1:8080”); ws.onopen = function (message) { }; ws.onclose = function (message) { }; ws.onmessage = function (message) { } @atmo_framework @asyncio
  • 47. WebSocket: Supported Browsers 10+ 10+ 6+ 5+ 10+ ? 2+ @atmo_framework @asyncio
  • 48. W3C API Ohhhhhhhhh •Pong/Ping: No exposed •Headers: Can’t add/read •Query String: No API, append them to the url •Cookie: Impossible to read them @atmo_framework @asyncio
  • 49. Atmosphere: First request •W3C Specification T 127.0.0.1:52212 -> 127.0.0.1:8080 [AP] GET /chat?X-Atmosphere-tracking-id=0&X-Atmosphere- Framework=2.2.0-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere- TrackMessageSize=true&X-Cache-Date=0&Content- Type=application/json&X-atmo-protocol=true HTTP/1.1. Upgrade: websocket. Connection: Upgrade. Host: 127.0.0.1:8080. Origin: http://127.0.0.1:8080. Sec-WebSocket-Key: TCBKrAyFFwW8HUXqLpj2wg==. Sec-WebSocket-Version: 13. Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame. @atmo_framework @asyncio
  • 50. Atmosphere: First request •W3C Specification T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] HTTP/1.1 101 Switching Protocols. X-Atmosphere-first-request: true. X-Atmosphere-tracking-id: bb7aeeb7-9e44-4aa9-848d-14bba6532de9. Connection: Upgrade. Sec-WebSocket-Accept: 5mHABDQFkWBtjoinv3lj+6dVwHg=. Upgrade: WebSocket. @atmo_framework @asyncio
  • 51. Problem #1 – onclose • Firefox will execute the ws.onclose function on F5 (reload) • Chrome/Safari ….. NOT! @atmo_framework @asyncio
  • 52. Problem #1: onclose •W3C Specification ws.onclose = function(closeReason) { switch(closeReason.code) { case 1000: …. } // Firefox will execute this logic on every reload // closeReason.wasClean unreliable if (dirtyClose) { reconnectTo(…); } } @atmo_framework @asyncio
  • 53. Atmosphere: onclose •W3C Specification // Hahahaha go to hell Firefox!! atmosphere.onClose = function (callback) { }; @atmo_framework @asyncio
  • 54. Problem #2 – Messages’ length • Messages can be truncated when the server write them • The Browser received them in two chunks or I/O operation @atmo_framework @asyncio
  • 55. Problem #2: Messages’ length •W3C Specification // Craaaaaaashhhhhhhhhhhhh ws.onmessage = function (callback) { window.JSON.parse(callback.data); }; @atmo_framework @asyncio
  • 56. Problem #2: What’s Up, Doctor! •W3C Specification // atmosphere.js transparently // handles it atmosphere.onMessage = function (callback) { window.JSON.parse(callback.responseBody); }; @atmo_framework @asyncio
  • 57. Problem #3 – UUID and Cookie • No Cookie to identify the client @atmo_framework @asyncio
  • 58. Problem #3 – UUID and Cookie • Solutions: • Normal request => set-cookie • Next WebSockets • Useful if you deploy on Amazon (1) HTTP (2) websockets @atmo_framework @asyncio
  • 59. Atmosphere: Handshake Protocol •W3C Specification T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] .651|bb7aeeb7-9e44-4aa9-848d-14bba6532de9|1397426374301| T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] .. T 127.0.0.1:8080 -> 127.0.0.1:52212 [AP] .. @atmo_framework @asyncio
  • 60. Problem #4 – Proxy • Proxy can close the websocket or completely ignore the websocket handshake, completely fooling the server…and the browser! • ws.open never called!!!! @atmo_framework @asyncio
  • 61. Problem #4 – Proxy •W3C Specification websocket.onopen = function (message) { alert(“Ha ha ha good luck!!!”); } websocket.onmessage = function(message) { // Never called alert(“Sleep on it!!!”); } @atmo_framework @asyncio
  • 62. Problem #4 – Proxy •W3C Specification atmosphere.onReopen = function (callback) { // Yeahhhh!!! }; atmosphere.onTransportFailure = function (callback) { // Apache Proxy, I hate you!!! }; @atmo_framework @asyncio
  • 64. Socket.IO and Socks.js SockJs et Socket.io blank slide for your own pictures @atmo_framework @asyncio
  • 65. Socket.IO • For Node.js • Streaming, Long-Polling and now Websocket • Extremely popular, lot of »issues » 602 => https://github.com/LearnBoost/socket.io/issues • Supported by Atmosphere, both client and server side. Replace node.js @atmo_framework @asyncio
  • 66. Socket.IO - Atmosphere @•ManWag3eCdS Serpveiccief(ipcaatthi o=n "/chat”) public class Chat { @Ready public void onReady(AtmosphereResource r) {..} @Disconnect public void onDisconnect(AtmosphereResourceEvent e) {..} @Message( encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class}) public Reply onMessage(Message message){ return handleAndReply(message); } } @atmo_framework @asyncio
  • 67. Socket.IO - Atmosphere •W3C Specification var socket = io.connect('', {'resource’:document.location.toString() + 'chat'}); socket.on('connect', function () { content.html($('<p>', { text:'Atmosphere connected using this.socket.transport.name})); }); socket.on('chat message', function() { var json = jQuery.parseJSON(msg); … } ); socket.on(‘error’, function (e) {…}); @atmo_framework @asyncio
  • 68. Socks.js •For Node.js •Emulate WebSocket, with « fallback » •Socks.js popularity increase, due to Spring 4, Vert.x and Atmosphere support @atmo_framework @asyncio
  • 69. Socks.js - Atmosphere @•ManWag3eCdS Serpveiccief(ipcaatthi o=n "/clavarder”) public class Chat { @Ready public void onReady(AtmosphereResource r) {..} @Disconnect public void onDisconnect(AtmosphereResourceEvent e) {..} @Message( encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class}) public Reply onMessage(Message message){ return handleAndReply(message); } } @atmo_framework @asyncio
  • 70. Socks.js- Atmosphere •W3C Specification var socket = new SockJS('http://' + window.location.host + '/chat', null, { 'protocols_whitelist': ['websocket', 'xhr-streaming', 'iframe-eventsource', 'iframe-htmlfile', 'xhr-polling', 'jsonp-polling'] }); socket.onopen = function() { content.html($('<p>', { text: 'Atmosphere connected using SockJs client'})); } socket.onmessage = function (response) { var message = response.data; var json = JSON.parse(message); } socket.onclose = function() { } @atmo_framework @asyncio
  • 71. Conclusion •WebSockets in Prod without fallback? You’re Crazy!! •Atmosphere is production ready, and fixes all the issues listed here! •What are you waiting for? @atmo_framework @asyncio
  • 72. @All images copyright JeanFrancois Arcand Credits https://www.linkedin.com/in/jfarcand http://async-io.org http://github.com/Atmosphere/atmosphere http://github.com/jfarcand @atmo_framework @asyncio