Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Server-Sent Events at Realtime Conf 2012

Server-Sent Events at Realtime Conf 2012

A look at the server-to-browser push spec called Server-Sent Events, also known as EventSource.

Luigi Ray-Montanez

October 24, 2012
Tweet

More Decks by Luigi Ray-Montanez

Other Decks in Programming

Transcript

  1. Overview Part 1: Why Server-Sent Events? Part 2: Implementing in

    the browser Part 3: Implementing on the server
  2. SPOILER ALERT Server-sent events are the right tool for the

    job in many scenarios. Try ‘em! You’ll like ‘em!
  3. Just TCP A lower level than HTTP Developer de!nes protocol

    Support XMPP, IRC, AMQP, VNC Some proxy servers not compatible
  4. In the Browser var source = new EventSource('/stream'); source.addEventListener('message', function(e)

    { console.log(e.data); }); source.addEventListener('open', function(e) { ... }); source.addEventListener('error', function(e) { ... });
  5. Data data: first line data: second line --- data: {

    data: "id": 12345, data: "msg": "hello world" data: } source.addEventListener('message', function(e) { var obj = JSON.parse(e.data); console.log(obj.id, obj.msg); });
  6. ID, Retry, Event id: 123 retry: 10000 data: AAPL data:

    572.44 --- data: {"msg": "First message"} event: userlogon data: {"username": "John123"} event: update data: {"username": "John123", "emotion": "happy"} source.addEventListener('userlogon', function(e) { ... source.addEventListener('update', function(e) { ...
  7. CORS Coming Soon var source = new EventSource('elsewhere.com/stream'); Spec in

    Draft @ W3C Implemented in Firefox & Opera Patch submitted for Webkit
  8. Node.js, part 1 var http = require('http'); var sys =

    require('sys'); var fs = require('fs'); http.createServer(function(req, res) { if (req.headers.accept && req.headers.accept == 'text/event-stream') { if (req.url == '/events') { sendSSE(req, res); } else { res.writeHead(404); res.end(); } } }).listen(8000);
  9. Node.js, part 2 function sendSSE(req, res) { res.writeHead(200, { 'Content-Type':

    'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); setInterval(function() { constructSSE(res, ‘time’, (new Date()).toLocaleTimeString()); }, 5000); } function constructSSE(res, event, data) { res.write('event: ' + event + '\n'); res.write("data: " + data + '\n\n'); }
  10. Rails 4, part 1 require 'json' class SSE def initialize(io)

    @io = io end def write(object, options = {}) options.each do |k,v| @io.write "#{k}: #{v}\n" end @io.write "data: #{JSON.dump(object)}\n\n" end def close @io.close end end
  11. Rails 4, part 2 require 'sse' class BrowserController < ApplicationController

    include ActionController::Live def index response.headers['Content-Type'] = 'text/event-stream' sse = SSE.new(response.stream) begin loop do sse.write({ :time => Time.now }) sleep 5 end rescue IOError # When the client disconnects, we'll get an IOError on write ensure sse.close end end end
  12. In Closing... When you need a sprinkling of realtime Server-to-browser

    push Simple, easy-to-implement spec Anti-complexity philosophy