SlideShare a Scribd company logo
Speed up Your Web Applications
with HTML5 WebSockets
Yakov Fain, Farata Systems, USA
Speed up your Web applications with HTML5 WebSockets
The Plan
- HTTP request-response
- Demo
- Server-Sent Events
- Demo
- WebSocket
- Demo
What Do You See?
HTTP Hacks
•  Polling
•  Long Polling
•  Streaming
Polling
Long Polling
Comet implementation: hanging GET or pending POST
Streaming
Getting Price Quotes from Google Finance
HTTP Request Response
Demo
Introducing the Demo
The Software
The Server:
GlassFish 4 (promoted build B88), Oracle
The server-side Java app can generate random price quotes
The Client:
HTML5 Ext JS framework, Sencha
The Browser: Chrome , Google
Charles Proxy
The Goal
1. The server generates random stock prices for a 12-stock portfolio
2. The user sends a request for price quote for a stock
3. The HTML client displays the received price
4. Observe what went over the network
The Server: Rest
	
  	
  @Path("stock")	
  
	
  	
  public	
  class	
  RestResource	
  {	
  
	
  	
  	
  	
  	
  	
  @GET	
  
	
  	
  	
  	
  	
  	
  @Produces(value	
  =	
  MediaType.APPLICATION_JSON)	
  
	
  	
  	
  	
  	
  	
  @Path("/{ticker}")	
  
	
  	
  	
  	
  	
  	
  public	
  String	
  getRandomValue(@PathParam(value	
  =	
  "ticker")	
  
String	
  ticker)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  return	
  new	
  
Gson().toJson(RandomStocksGenerator.getDataForTicker(ticker));	
  
	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  }	
  
	
  	
  }	
  
	
  	
  
The Client: AJAX in Ext JS
	
  	
  	
  	
  'mypanel	
  button[action=doRestCall]':	
  	
  
	
  	
  	
  	
  	
  	
  	
  	
  click:	
  this.onRestCall	
  	
  	
  
onRestCall:	
  function(btn)	
  {	
  
	
  	
  var	
  ticker	
  =	
  Ext.ComponentQuery.query('mypanel	
  textfield[name=ticker]')
[0].getValue();	
  
	
  	
  var	
  rest_url	
  =	
  "http://"	
  +	
  document.location.host	
  +	
  
document.location.pathname	
  +	
  "rest/stock/";	
  
	
  	
  rest_url	
  =	
  rest_url	
  +	
  ticker;	
  
	
  
	
  	
  Ext.Ajax.request({	
  
	
  	
  	
  	
  	
  	
  url:	
  rest_url,	
  
	
  	
  	
  	
  	
  	
  scope:	
  this,	
  
	
  	
  	
  	
  	
  	
  success:	
  function(response)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  var	
  a	
  =	
  Ext.JSON.decode(response.responseText);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  a.price	
  =	
  parseFloat(a.price).toFixed(4);	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  console.log(a);	
  
	
  	
  	
  	
  	
  	
  }	
  
	
  	
  });	
  
}
Server-Sent Events
What’s SSE
•  It’s not a request-response mode
•  The browser subscribes to events from server
by creating EventSource pointing to this server
•  The server can send data to client at any time
•  The browser receives an event + data
Browser Subscribes to SSE
To listen to any messages: 	
  source.onmessage	
  =	
  function(e)	
  {….};	
  
var	
  source	
  =	
  new	
  EventSource('http://localhost:8080/stock/events');	
  
	
  
source.addEventListener('open',	
  function(e)	
  {	
  
	
  	
  //	
  Connection	
  was	
  opened.	
  
},	
  false);	
  
	
  
source.addEventListener('priceChanged',	
  function(e)	
  {	
  
	
  	
  var	
  priceQuote	
  =	
  JSON.parse(e.data);	
  
	
  	
  //…	
  
},	
  false);	
  
	
  
source.addEventListener('error',	
  function(e)	
  {	
  
	
  	
  if	
  (e.readyState	
  ==	
  EventSource.CLOSED)	
  {	
  
	
  	
  	
  	
  //	
  Connection	
  was	
  closed.	
  
	
  	
  }	
  
},	
  false);	
  
Pushing SSE from Server
The server sends events as text messages with MIME
text/event-­‐stream	
  	
  
Each message starts with data: and end with a pair /n/n:
'data:	
  {"price":	
  "123.45"}/n/n'	
  
The browser concatenates all these messages separating
them with /n.
Pushing from Glassfish (Jersey)
@Path("stock")	
  
public	
  class	
  SseResource	
  {	
  
	
  	
  private	
  static	
  final	
  SseBroadcaster	
  BROADCASTER	
  =	
  	
  
	
   	
   	
   	
   	
  new	
  SseBroadcaster();	
  
	
  
	
  	
  private	
  boolean	
  isRunning	
  =	
  false;	
  
	
  	
  private	
  Timer	
  broadcastTimer;	
  
	
  
	
  	
  @GET	
  
	
  	
  @Path("stock-­‐generator")	
  
	
  	
  @Produces(SseFeature.SERVER_SENT_EVENTS)	
  
	
  	
  public	
  EventOutput	
  itemEvents()	
  {	
  
	
  	
  	
  	
  final	
  EventOutput	
  eventOutput	
  =	
  new	
  EventOutput();	
  
	
  	
  	
  	
  BROADCASTER.add(eventOutput);	
  
	
  	
  	
  	
  if	
  (!isRunning)	
  startBroadcastTask();	
  
	
  	
  	
  	
  return	
  eventOutput;	
  
	
  	
  }	
  
}
Broadcasting in Jersey
protected	
  void	
  startBroadcastTask()	
  {	
  
	
  broadcastTimer	
  =	
  new	
  Timer();	
  
	
  broadcastTimer	
  
	
  .schedule(new	
  SseBroadcastTask(BROADCASTER,	
  0),	
  0,	
  300);	
  
	
  this.isRunning	
  =	
  true;	
  
}
public	
  class	
  SseBroadcastTask	
  extends	
  TimerTask	
  {	
  
private	
  final	
  SseBroadcaster	
  owner;	
  
	
  
public	
  SseBroadcastTask(SseBroadcaster	
  owner,	
  int	
  timeout)	
  {	
  
	
  	
  this.owner	
  =	
  owner;	
  
}	
  
	
  
@Override	
  
public	
  void	
  run()	
  {	
  
	
  	
  OutboundEvent	
  event	
  =	
  new	
  OutboundEvent.Builder().data(	
  
	
  	
  	
  	
  	
  String.class,	
  
RandomStocksGenerator.getRandomValues().toJson()).build();	
  
	
  	
  owner.broadcast(event);	
  
Push With Serer-Sent Events
Demo
Introducing the SSE Demo
The Software
The Server:
GlassFish 4 (promoted build B88), Oracle
The Java app can generate random price quotes
The Client:
HTML5 Ext JS framework, Sencha
The Chrome Browser, Google
The Goal
1. The server generates random stock prices for a 12-stock portfolio
2. The server pushes 3 price quotes per second using SSE
3. The HTML client shows the prices in a data grid
WebSocket
WebSocket
•  Standard W3C protocol (RFC6455)
•  Java EE 7 includes WebSocket API (JSR-356)
•  Web Browsers include window.WebSocket
object. No plugins required.
How WebSocket Works
Establish a socket connection via HTTP for the initial handshake.
Switch the protocol from HTTP to a socket-based protocol.
Send messages in both directions simultaneously.
This is not a request-response model!
Protocol Upgrade: HTTP à WebSocket
•  Client sends Upgrade HTTP-request
•  Server confirms Upgrade
•  Client receives Upgrade response from server
•  Client changes WebSocket.readyState to open
HTTP://… HTTPS://…
WS://… WSS://…
URI Schemes
The wss encryption is done the same way as in https
W3C: WebSocket Interface
[Constructor(DOMString	
  url,	
  optional	
  (DOMString	
  or	
  DOMString[])	
  protocols)]	
  
interface	
  WebSocket	
  :	
  EventTarget	
  {	
  
	
  	
  readonly	
  attribute	
  DOMString	
  url;	
  
	
  
	
  	
  const	
  unsigned	
  short	
  CONNECTING	
  =	
  0;	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  const	
  unsigned	
  short	
  OPEN	
  =	
  1;	
  
	
  	
  const	
  unsigned	
  short	
  CLOSING	
  =	
  2;	
  
	
  	
  const	
  unsigned	
  short	
  CLOSED	
  =	
  3;	
  
	
  	
  readonly	
  attribute	
  unsigned	
  short	
  readyState;	
  
	
  	
  readonly	
  attribute	
  unsigned	
  long	
  bufferedAmount;	
  
	
  
	
  	
  //	
  networking	
  
	
  	
  [TreatNonCallableAsNull]	
  attribute	
  Function?	
  onopen;	
  	
  	
  	
  	
  	
  	
  
	
  	
  [TreatNonCallableAsNull]	
  attribute	
  Function?	
  onerror;	
  
	
  	
  [TreatNonCallableAsNull]	
  attribute	
  Function?	
  onclose;	
  
	
  	
  readonly	
  attribute	
  DOMString	
  extensions;	
  
	
  	
  readonly	
  attribute	
  DOMString	
  protocol;	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  void	
  close([Clamp]	
  optional	
  unsigned	
  short	
  code,	
  optional	
  DOMString	
  reason);	
  
	
  
	
  	
  //	
  messaging	
  
	
  	
  [TreatNonCallableAsNull]	
  attribute	
  Function?	
  onmessage;	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  attribute	
  DOMString	
  binaryType;	
  
	
  	
  void	
  send(DOMString	
  data);	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  void	
  send(ArrayBufferView	
  data);	
  
	
  	
  void	
  send(Blob	
  data);	
  
};
@ServerEndpoint in Java EE
Client
Your Java Endpoint
and other classes
POJO
Decoder
Encoder
WebSocket Endpoint
	
  @ServerEndpoint(value	
  =	
  "/stock-­‐generator",	
  
	
  	
  	
  	
  	
  	
  	
  	
  encoders	
  =	
  {	
  StockMessageEncoder.class	
  },	
  
	
  	
  	
  	
  	
  	
  	
  	
  decoders	
  =	
  {	
  StockMessageDecoder.class	
  })	
  
public	
  class	
  StocksEndpoint	
  {	
  
	
  	
  	
  	
  	
  @OnOpen	
  
	
  	
  	
  	
  	
  public	
  void	
  onOpen(Session	
  session)	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  …	
  
	
  	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  @OnMessage	
  
	
  	
  	
  	
  public	
  void	
  onMessage(StockMessage	
  message,	
  Session	
  client)	
  {	
  
	
  
	
  	
  	
  	
  }	
  
	
  
	
  	
  	
  	
  	
  @OnClose	
  
	
  	
  	
  	
  	
  public	
  void	
  onClose(Session	
  session)	
  {…	
  
	
  	
  	
  	
  	
  	
  	
  	
  …	
  
	
  	
  	
  	
  	
  	
  }	
  
	
  	
  	
  	
  …	
  
}
public	
  class	
  StockMessageDecoder	
  implements	
  
Decoder.Text<StockMessage>	
  {	
  
	
  
	
  	
  	
  @Override	
  
	
  	
  	
  public	
  StockMessage	
  decode(String	
  s)	
  throws	
  DecodeException	
  {	
  
	
  	
  	
  	
  	
  	
  	
  Gson	
  gson	
  =	
  new	
  Gson();	
  
	
  	
  	
  	
  	
  	
  	
  return	
  gson.fromJson(s,	
  StockMessage.class);	
  
	
  	
  	
  }	
  
}
public	
  class	
  StockMessageEncoder	
  implements	
  
Encoder.Text<StockMessage>	
  {	
  
	
  	
  	
  	
  	
  
	
  	
  	
  @Override	
  
	
  	
  	
  	
  public	
  String	
  encode(StockMessage	
  object)	
  throws	
  
EncodeException	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  return	
  new	
  Gson().toJson(object);	
  
	
  	
  	
  	
  }	
  
}
Decoder
Encoder
Heartbeats: Pings and Pongs
Heartbeats is a mechanism to
check that connection is still alive.
If a WebSocket implementation
receives a ping it has
to respond with a pong ASAP.
There is no JavaScript API to support Pings and Pongs.
Web Socket Demo
The Software
The Server:
GlassFish 4 (promoted build B88), Oracle
The Java app can generate random price quotes
The Client:
HTML5 Ext JS framework, Sencha
The Chrome Browser, Google
Charles proxy
Introducing the WebSocket Demo
The Goal
1. The server generates random stock prices for a 12-stock portfolio
2. The server pushes 20 price quotes per second using WebSocket
3. The HTML client shows the prices in a data grid
What was Pushed via WebSocket
The size of each data push:
The length price quote data: from 42 to 45 bytes
WebSocket added overhead: 2 bytes
{"symbol":	
  "APPL",	
  "id":	
  555,	
  "price":	
  "451.29"}	
  
Comparing Overheads
Http Request-Response
Each roundtrip has:
request header: 429 bytes + 268 bytes response header
+ 46 bytes data
Server-Sent Events
Initial request header 406 bytes + 268 bytes response
header
Each push: 46 bytes data + 8 bytes message wrapper
WebSocket
Initial upgrade request: 406 bytes + 268 bytes
Each push 46 bytes data + 2 bytes message wrapper
It’s full-duplex, not HTTP-based, works much faster.
Caniuse.com: Browser Support
Reducing kilobytes of data to 2 bytes...
and reducing latency from 150ms to 50 ms
is far more than marginal.
In fact, these two factors alone are enough
to make WebSocket seriously interesting to
Google.
Ian Hickson, Google
The lead HTML5 writer
Where to use WebSockets
- Live trading/sports ticker
- Controlling medical equipment over the web
- Chat applications
- Multiplayer online games
- Real-time updating social streams
Unedited drafts of the book Enterprise Web Development are published at
enterprisewebbook.com
Contact Info
Farata Systems: faratasystems.com
Personal blog: yakovfain.com
Twitter: @yfain
Podcasts in Russian: americhka.us
Thank you!

More Related Content

PDF
Seven Versions of One Web Application
PDF
Dart for Java Developers
PDF
Intro to JavaScript
PPTX
Single Page Applications with AngularJS 2.0
PDF
Tech Webinar: Angular 2, Introduction to a new framework
PDF
Overview of the AngularJS framework
PDF
Angular2 Development for Java developers
PDF
Exploring Angular 2 - Episode 1
Seven Versions of One Web Application
Dart for Java Developers
Intro to JavaScript
Single Page Applications with AngularJS 2.0
Tech Webinar: Angular 2, Introduction to a new framework
Overview of the AngularJS framework
Angular2 Development for Java developers
Exploring Angular 2 - Episode 1

What's hot (20)

PDF
Angular 2 Essential Training
PPTX
Angular js 2
PPTX
PDF
Web sockets in Angular
ODP
Introduction to Angular 2
PDF
Angular 2 - The Next Framework
ODP
Angularjs
PDF
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
PPTX
AngularJs presentation
PPTX
Angular 4
PDF
Reactive Thinking in Java with RxJava2
PDF
Angular 4 for Java Developers
PDF
Data Flow Patterns in Angular 2 - Sebastian Müller
PDF
Angular2 - In Action
PPTX
Angular2 for Beginners
PDF
Commit University - Exploring Angular 2
PDF
AngularJS application architecture
PDF
RESTful services and OAUTH protocol in IoT
PPTX
Async patterns in javascript
PDF
Create Your Own Framework by Fabien Potencier
Angular 2 Essential Training
Angular js 2
Web sockets in Angular
Introduction to Angular 2
Angular 2 - The Next Framework
Angularjs
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
AngularJs presentation
Angular 4
Reactive Thinking in Java with RxJava2
Angular 4 for Java Developers
Data Flow Patterns in Angular 2 - Sebastian Müller
Angular2 - In Action
Angular2 for Beginners
Commit University - Exploring Angular 2
AngularJS application architecture
RESTful services and OAUTH protocol in IoT
Async patterns in javascript
Create Your Own Framework by Fabien Potencier
Ad

Similar to Speed up your Web applications with HTML5 WebSockets (20)

PDF
Joe Walker Interactivewebsites Cometand Dwr
PPTX
13 networking, mobile services, and authentication
PPT
Network
PPT
DWR, Hibernate and Dojo.E - A Tutorial
PDF
Laporan multiclient chatting client server
PDF
WebSockets Jump Start
PDF
Building interactivity with websockets
PPTX
Servlets
PDF
Spring Web Services: SOAP vs. REST
PDF
Nodejs and WebSockets
PDF
GWT Web Socket and data serialization
PDF
softshake 2014 - Java EE
PDF
Spring 4 Web App
PPT
Pemrograman Jaringan
PPTX
Node.js System: The Approach
PDF
Websockets talk at Rubyconf Uruguay 2010
PDF
Durable functions 2.0 (2019-10-10)
PDF
Chapter 27 Networking - Deitel & Deitel
PDF
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
PPTX
#3 (Multi Threads With TCP)
Joe Walker Interactivewebsites Cometand Dwr
13 networking, mobile services, and authentication
Network
DWR, Hibernate and Dojo.E - A Tutorial
Laporan multiclient chatting client server
WebSockets Jump Start
Building interactivity with websockets
Servlets
Spring Web Services: SOAP vs. REST
Nodejs and WebSockets
GWT Web Socket and data serialization
softshake 2014 - Java EE
Spring 4 Web App
Pemrograman Jaringan
Node.js System: The Approach
Websockets talk at Rubyconf Uruguay 2010
Durable functions 2.0 (2019-10-10)
Chapter 27 Networking - Deitel & Deitel
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
#3 (Multi Threads With TCP)
Ad

More from Yakov Fain (15)

PDF
Type script for_java_dev_jul_2020
PDF
Using JHipster for generating Angular/Spring Boot apps
PDF
Using JHipster for generating Angular/Spring Boot apps
PDF
TypeScript for Java Developers
PDF
Reactive Streams and RxJava2
PDF
Using JHipster 4 for generating Angular/Spring Boot apps
PDF
Reactive programming in Angular 2
PDF
Reactive Thinking in Java
PDF
Angular 2 for Java Developers
PDF
Integrating consumers IoT devices into Business Workflow
PDF
Java Intro: Unit1. Hello World
PDF
Running a Virtual Company
PDF
Princeton jug git_github
PDF
Surviving as a Professional Software Developer
PDF
Becoming a professional software developer
Type script for_java_dev_jul_2020
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
TypeScript for Java Developers
Reactive Streams and RxJava2
Using JHipster 4 for generating Angular/Spring Boot apps
Reactive programming in Angular 2
Reactive Thinking in Java
Angular 2 for Java Developers
Integrating consumers IoT devices into Business Workflow
Java Intro: Unit1. Hello World
Running a Virtual Company
Princeton jug git_github
Surviving as a Professional Software Developer
Becoming a professional software developer

Recently uploaded (20)

PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
cuic standard and advanced reporting.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Electronic commerce courselecture one. Pdf
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Big Data Technologies - Introduction.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Machine learning based COVID-19 study performance prediction
MIND Revenue Release Quarter 2 2025 Press Release
“AI and Expert System Decision Support & Business Intelligence Systems”
cuic standard and advanced reporting.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Empathic Computing: Creating Shared Understanding
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Network Security Unit 5.pdf for BCA BBA.
20250228 LYD VKU AI Blended-Learning.pptx
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Chapter 3 Spatial Domain Image Processing.pdf
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Electronic commerce courselecture one. Pdf
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Big Data Technologies - Introduction.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
NewMind AI Weekly Chronicles - August'25 Week I
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Machine learning based COVID-19 study performance prediction

Speed up your Web applications with HTML5 WebSockets

  • 1. Speed up Your Web Applications with HTML5 WebSockets Yakov Fain, Farata Systems, USA
  • 3. The Plan - HTTP request-response - Demo - Server-Sent Events - Demo - WebSocket - Demo
  • 4. What Do You See?
  • 5. HTTP Hacks •  Polling •  Long Polling •  Streaming
  • 7. Long Polling Comet implementation: hanging GET or pending POST
  • 9. Getting Price Quotes from Google Finance
  • 11. Introducing the Demo The Software The Server: GlassFish 4 (promoted build B88), Oracle The server-side Java app can generate random price quotes The Client: HTML5 Ext JS framework, Sencha The Browser: Chrome , Google Charles Proxy The Goal 1. The server generates random stock prices for a 12-stock portfolio 2. The user sends a request for price quote for a stock 3. The HTML client displays the received price 4. Observe what went over the network
  • 12. The Server: Rest    @Path("stock")      public  class  RestResource  {              @GET              @Produces(value  =  MediaType.APPLICATION_JSON)              @Path("/{ticker}")              public  String  getRandomValue(@PathParam(value  =  "ticker")   String  ticker)  {                            return  new   Gson().toJson(RandomStocksGenerator.getDataForTicker(ticker));                        }      }      
  • 13. The Client: AJAX in Ext JS        'mypanel  button[action=doRestCall]':                    click:  this.onRestCall       onRestCall:  function(btn)  {      var  ticker  =  Ext.ComponentQuery.query('mypanel  textfield[name=ticker]') [0].getValue();      var  rest_url  =  "http://"  +  document.location.host  +   document.location.pathname  +  "rest/stock/";      rest_url  =  rest_url  +  ticker;        Ext.Ajax.request({              url:  rest_url,              scope:  this,              success:  function(response)  {                      var  a  =  Ext.JSON.decode(response.responseText);                      a.price  =  parseFloat(a.price).toFixed(4);                      console.log(a);              }      });   }
  • 15. What’s SSE •  It’s not a request-response mode •  The browser subscribes to events from server by creating EventSource pointing to this server •  The server can send data to client at any time •  The browser receives an event + data
  • 16. Browser Subscribes to SSE To listen to any messages:  source.onmessage  =  function(e)  {….};   var  source  =  new  EventSource('http://localhost:8080/stock/events');     source.addEventListener('open',  function(e)  {      //  Connection  was  opened.   },  false);     source.addEventListener('priceChanged',  function(e)  {      var  priceQuote  =  JSON.parse(e.data);      //…   },  false);     source.addEventListener('error',  function(e)  {      if  (e.readyState  ==  EventSource.CLOSED)  {          //  Connection  was  closed.      }   },  false);  
  • 17. Pushing SSE from Server The server sends events as text messages with MIME text/event-­‐stream     Each message starts with data: and end with a pair /n/n: 'data:  {"price":  "123.45"}/n/n'   The browser concatenates all these messages separating them with /n.
  • 18. Pushing from Glassfish (Jersey) @Path("stock")   public  class  SseResource  {      private  static  final  SseBroadcaster  BROADCASTER  =              new  SseBroadcaster();        private  boolean  isRunning  =  false;      private  Timer  broadcastTimer;        @GET      @Path("stock-­‐generator")      @Produces(SseFeature.SERVER_SENT_EVENTS)      public  EventOutput  itemEvents()  {          final  EventOutput  eventOutput  =  new  EventOutput();          BROADCASTER.add(eventOutput);          if  (!isRunning)  startBroadcastTask();          return  eventOutput;      }   }
  • 19. Broadcasting in Jersey protected  void  startBroadcastTask()  {    broadcastTimer  =  new  Timer();    broadcastTimer    .schedule(new  SseBroadcastTask(BROADCASTER,  0),  0,  300);    this.isRunning  =  true;   } public  class  SseBroadcastTask  extends  TimerTask  {   private  final  SseBroadcaster  owner;     public  SseBroadcastTask(SseBroadcaster  owner,  int  timeout)  {      this.owner  =  owner;   }     @Override   public  void  run()  {      OutboundEvent  event  =  new  OutboundEvent.Builder().data(            String.class,   RandomStocksGenerator.getRandomValues().toJson()).build();      owner.broadcast(event);  
  • 20. Push With Serer-Sent Events Demo
  • 21. Introducing the SSE Demo The Software The Server: GlassFish 4 (promoted build B88), Oracle The Java app can generate random price quotes The Client: HTML5 Ext JS framework, Sencha The Chrome Browser, Google The Goal 1. The server generates random stock prices for a 12-stock portfolio 2. The server pushes 3 price quotes per second using SSE 3. The HTML client shows the prices in a data grid
  • 23. WebSocket •  Standard W3C protocol (RFC6455) •  Java EE 7 includes WebSocket API (JSR-356) •  Web Browsers include window.WebSocket object. No plugins required.
  • 24. How WebSocket Works Establish a socket connection via HTTP for the initial handshake. Switch the protocol from HTTP to a socket-based protocol. Send messages in both directions simultaneously. This is not a request-response model!
  • 25. Protocol Upgrade: HTTP à WebSocket •  Client sends Upgrade HTTP-request •  Server confirms Upgrade •  Client receives Upgrade response from server •  Client changes WebSocket.readyState to open
  • 26. HTTP://… HTTPS://… WS://… WSS://… URI Schemes The wss encryption is done the same way as in https
  • 27. W3C: WebSocket Interface [Constructor(DOMString  url,  optional  (DOMString  or  DOMString[])  protocols)]   interface  WebSocket  :  EventTarget  {      readonly  attribute  DOMString  url;        const  unsigned  short  CONNECTING  =  0;                          const  unsigned  short  OPEN  =  1;      const  unsigned  short  CLOSING  =  2;      const  unsigned  short  CLOSED  =  3;      readonly  attribute  unsigned  short  readyState;      readonly  attribute  unsigned  long  bufferedAmount;        //  networking      [TreatNonCallableAsNull]  attribute  Function?  onopen;                  [TreatNonCallableAsNull]  attribute  Function?  onerror;      [TreatNonCallableAsNull]  attribute  Function?  onclose;      readonly  attribute  DOMString  extensions;      readonly  attribute  DOMString  protocol;                                              void  close([Clamp]  optional  unsigned  short  code,  optional  DOMString  reason);        //  messaging      [TreatNonCallableAsNull]  attribute  Function?  onmessage;                        attribute  DOMString  binaryType;      void  send(DOMString  data);                              void  send(ArrayBufferView  data);      void  send(Blob  data);   };
  • 28. @ServerEndpoint in Java EE Client Your Java Endpoint and other classes POJO Decoder Encoder
  • 29. WebSocket Endpoint  @ServerEndpoint(value  =  "/stock-­‐generator",                  encoders  =  {  StockMessageEncoder.class  },                  decoders  =  {  StockMessageDecoder.class  })   public  class  StocksEndpoint  {            @OnOpen            public  void  onOpen(Session  session)  {                  …            }            @OnMessage          public  void  onMessage(StockMessage  message,  Session  client)  {            }              @OnClose            public  void  onClose(Session  session)  {…                  …              }          …   }
  • 30. public  class  StockMessageDecoder  implements   Decoder.Text<StockMessage>  {          @Override        public  StockMessage  decode(String  s)  throws  DecodeException  {                Gson  gson  =  new  Gson();                return  gson.fromJson(s,  StockMessage.class);        }   } public  class  StockMessageEncoder  implements   Encoder.Text<StockMessage>  {                  @Override          public  String  encode(StockMessage  object)  throws   EncodeException  {                  return  new  Gson().toJson(object);          }   } Decoder Encoder
  • 31. Heartbeats: Pings and Pongs Heartbeats is a mechanism to check that connection is still alive. If a WebSocket implementation receives a ping it has to respond with a pong ASAP. There is no JavaScript API to support Pings and Pongs.
  • 33. The Software The Server: GlassFish 4 (promoted build B88), Oracle The Java app can generate random price quotes The Client: HTML5 Ext JS framework, Sencha The Chrome Browser, Google Charles proxy Introducing the WebSocket Demo The Goal 1. The server generates random stock prices for a 12-stock portfolio 2. The server pushes 20 price quotes per second using WebSocket 3. The HTML client shows the prices in a data grid
  • 34. What was Pushed via WebSocket The size of each data push: The length price quote data: from 42 to 45 bytes WebSocket added overhead: 2 bytes {"symbol":  "APPL",  "id":  555,  "price":  "451.29"}  
  • 35. Comparing Overheads Http Request-Response Each roundtrip has: request header: 429 bytes + 268 bytes response header + 46 bytes data Server-Sent Events Initial request header 406 bytes + 268 bytes response header Each push: 46 bytes data + 8 bytes message wrapper WebSocket Initial upgrade request: 406 bytes + 268 bytes Each push 46 bytes data + 2 bytes message wrapper It’s full-duplex, not HTTP-based, works much faster.
  • 37. Reducing kilobytes of data to 2 bytes... and reducing latency from 150ms to 50 ms is far more than marginal. In fact, these two factors alone are enough to make WebSocket seriously interesting to Google. Ian Hickson, Google The lead HTML5 writer
  • 38. Where to use WebSockets - Live trading/sports ticker - Controlling medical equipment over the web - Chat applications - Multiplayer online games - Real-time updating social streams
  • 39. Unedited drafts of the book Enterprise Web Development are published at enterprisewebbook.com
  • 40. Contact Info Farata Systems: faratasystems.com Personal blog: yakovfain.com Twitter: @yfain Podcasts in Russian: americhka.us Thank you!