Server-Sent Events in Action

21
Server Sent Events In Action Andrei Rusu May 30th, 2013

description

A talk I've done during a Fronteers meet-up (fronteers.nl) hosted by eBuddy on the subject of server-sent events, a recent HTML5 connectivity API.

Transcript of Server-Sent Events in Action

Page 1: Server-Sent Events in Action

Server Sent EventsIn Action

Andrei RusuMay 30th, 2013

Page 2: Server-Sent Events in Action

Who is eBuddy?• Web and mobile messaging for

everyone, everywhere!

• Two main messaging products: eBuddy Chat and XMS

• XMS is a real-time messaging app for smartphones

Page 3: Server-Sent Events in Action

+

Page 4: Server-Sent Events in Action

• Companion web app

• User needs to register on their mobile client

• Supports several authentication mechanisms

• Designed to bring additional features

Page 5: Server-Sent Events in Action

• HTML5 draft specification for implementing real-time HTTP streaming

• Enables a web browser to receive push-like notifications from a server

• New EventSource Javascript API

• Implemented in Web XMS - web.xms.me

Server ... what?

Page 6: Server-Sent Events in Action

Implementation goals

• Improve the scalability of the application in terms of concurrent users

• Speedy communication with the backend service

• Improve the connection handling and stability

• HTML5 makes us look cool

Page 7: Server-Sent Events in Action

Real-time communicationsThe dark days:

• Polling (short / long lived HTTP requests)

• Comet and reverse ajax

• Never-ending IFRAME(s) / script tags

• Flash sockets (since ActionScript 3)

Page 8: Server-Sent Events in Action

HTML5 to the rescue!

• New connectivity APIs for scalable client-server messaging

• XHR2, WebSockets, Server-Sent Events

• No more iframe or script tag hacks

Page 9: Server-Sent Events in Action

XMLHttpRequest Level 2

• Removes cross-domain http restrictions - Cross-Origin Resource Sharing (CORS)

• http://an.example.com can directly connect to http://other.example.org

• Destination server must add some response headers:Access-Control-Allow-Origin: http://an.example.orgAccess-Control-Request-Method: GET, POSTAccess-Control-Request-Headers: X-Requested-WithHost: other.example.org

• More event handlers for tracking the progress of the request

Page 10: Server-Sent Events in Action

WebSockets

• Full-duplex, bi-directional communication channel

• Client connects to socket server and sends and receives messages real-time

• “Upgrades” an HTTP connection to a WebSocket connection over the same TCP/IP channel

• Works over firewalls and gateways

Page 11: Server-Sent Events in Action

Server-sent Events

• One-way message streaming over traditional HTTP

• Client subscribes to server and waits (long-lived HTTP channel)

• When there’s data, server generates event and pushes the data to client

• No special server protocol implementation

• New EventSource HTML5 api

Page 12: Server-Sent Events in Action

EventStream Format

HTTP/1.1 200 OKContent-Type: text/event-stream

data: This is the first message.

event: notificationdata: This is the second message, itdata: has two lines.

id: 12345data: This is the third message with an id

Page 13: Server-Sent Events in Action

• var source = new EventSource(“https://{backend_server}/subscribe?access_token=XYZ&client_id=123”);source.addEventListener(“open”, function(e) { // connected});

source.addEventListener(“error”, function(e) { switch (this.readyState) { case EventSource.CONNECTING: // trying to reconnect ... break; case EventSource.CLOSE: // connection closed break; }});

source.addEventListener(“message”, function(e) { // message received});

source.addEventListener(“bind_result”, function(e) { var session = JSON.parse(e.data);});

• No HTTP overhead - one single subscribe request

• Updates are streamed real-time

• Publish is done via regular XHR with CORS support

EventSource

Page 14: Server-Sent Events in Action

Current Architecture

Backend

GET /poll HTTP/1.1

Browser

10s

HTTP/1.1 200 OK: {empty}

55s

HTTP/1.1 200 OK: {message: “Hello there!”, seq=99}

55s

GET /poll HTTP/1.1

HTTP/1.1 200 OK: {empty}

GET /poll HTTP/1.1

Page 15: Server-Sent Events in Action

Current Web XMS Setup

Client

nginxproxy

POLL

Auth Service

Load balancer

Node.jsservice

LOGIN

Application server 1

Application server 2

Application server NCassandra

1. authorize2. loadbalance3. get_client_settings4. etc.

POLL {server_address}

access_tokenserver_address

settings

access_token

Page 16: Server-Sent Events in Action

• No direct connections - polls have to go through the proxy

• HTTP Overhead: TCP handshakes, headers, cookies etc.

• Scaling is difficult

Problems with polling

Page 17: Server-Sent Events in Action

Server-Sent Events Architecture

Backend

new EventSource(‘/subscribe?access_token=XYZ&client_id=ABC)

Browser

close()

id: 1event: bind_resultdata: {session_id: “12143-333-31314124”}

id: 2event: message_receiveddata: {message: “Hello there!”, seq=99}

HTTP/1.1 200 OK text/event-stream

HTTP/1.1 200 OK text/event-stream

Page 18: Server-Sent Events in Action

New Setup

Client

Auth Service

Load balancer

Node.jsservice

LOGIN

Application server 1

Application server 2

Application server NCassandra

1. authorize2. loadbalance3. get_client_settings4. etc.

EventSource {server_address}

access_tokenserver_address

settings

Page 19: Server-Sent Events in Action

• Connection is recovered automatically

• Server needs to send keep-alive messages to keep the channel open

• Internet Explorer can emulate EventSource using regular XMLHttpRequest (XDomainRequest in IE9 and below) - polyfill libraries

• Safari doesn’t support EventSource with CORS

Error handling

Page 20: Server-Sent Events in Action

• EventSource has better browser support and pretty good fallback mechanism

• WebSockets needs HTTP as fallback ultimately

• Long-polling -> EventSource -> WebSocket

Why not WebSockets?

Page 21: Server-Sent Events in Action

Thanks!visit http://xms.me to download XMS!