WebSockets
and the Real-Time Web

         tossug 2010-07-06
  Chia-liang Kao clkao@clkao.org
clkao
Real-Time
  Web
New information
without refreshing
 the “web-page”
Real-time Spam
COSCUP Regisration
     Status
COSCUP Regisration
     Status
Real-time Annoyance
Real-time
market quotes
DEMO
Outlines
• comet server-push technologies
• websockets introductions
• websockets examples
• frameworks and packages
 supporting websockets
Server-Push

• browser tells server about interested
  information
• information streamed from server to
  browser without explicit request
Comet
Comet
Comet
Comet
The word comet came to English by way of the Latin word cometes. This word, in turn, came
from the Greek word κόμη, which means "hair of the head". The Greek scientist and
philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw
as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with
three hairlike extensions.




• 2006, coined by Alex Russell
• Server push for real time notification
Widely used

• gmail
• plurk
• facebook updates
Comet - Long-poll

• Browser connects to an event endpoint
• connection idled when there’s no event
• browser reconnects after receiving events
Comet - Forever IFrame

• Makes use of browser incremental
  rendering
 • IE wants <br/>
 • Safari wants 1KB data
• cross-iframe messaging
Multi-part XHR
   • multi-part response with boundries:
Content-Type: multipart/mixed; boundary=Foo

--Foo
Content-Type: application/json

{foo: 1}
--Foo
Content-Type: application/json

{foo: 2}
Multi-part XHR
   • multi-part response with boundries:
Content-Type: multipart/mixed; boundary=Foo

--Foo
Content-Type: application/json

{foo: 1}
--Foo
Content-Type: application/json

{foo: 2}
Lots of hacks!
Lots of hacks!

• spinning “loading” indicator for FF and IE
Lots of hacks!

• spinning “loading” indicator for FF and IE
• number of connections limits
Lots of hacks!

• spinning “loading” indicator for FF and IE
• number of connections limits
• transport overhead
Lots of hacks!

• spinning “loading” indicator for FF and IE
• number of connections limits
• transport overhead
• webserver connections overhead
Lots of hacks!

• spinning “loading” indicator for FF and IE
• number of connections limits
• transport overhead
• webserver connections overhead
• ...... orz
Enter
WebSockets
Websockets
Websockets

• HTML5 Websockets
Websockets

• HTML5 Websockets
• Bidirectional communication over HTTP
Websockets

• HTML5 Websockets
• Bidirectional communication over HTTP
• Available in latest browsers
Websockets

• HTML5 Websockets
• Bidirectional communication over HTTP
• Available in latest browsers
• or use http://github.com/gimite/web-socket-js
ws://example.com

wss://example.com
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com

^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
Request:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com
                              New in draft#76
^n:ds[4U   Response:
           HTTP/1.1 101 WebSocket Protocol Handshake
           Upgrade: WebSocket
           Connection: Upgrade
           Sec-WebSocket-Origin: http://example.com
           Sec-WebSocket-Location: ws://example.com/demo
           Sec-WebSocket-Protocol: sample

           8jKS'y:G*Co,Wxa-
my @keys = map {
    my $k = $env>{'HTTP_SEC_WEBSOCKET_KEY'.$_};
    join('', $k =~ m/d/g) / scalar @{[$k =~ m/ /g]};
} (1,2);

md5(pack('NN', @keys) . $key3);
Messages surrounded
by x{00} and x{ff}
Websockets API
Websockets API

ws = new WebSocket("ws://foo.com:5000”));

ws.onopen = function(ev) { ... }
ws.onmessage = function(ev) { ... }
ws.onclose = function(ev) { ... }
ws.onerror = function(ev) { ... }

ws.send(....);
DEMO
WebSockets
Challenges
Browser
Support
Browser
  web-socket-js
Support
  to the rescue!!
Session Management

• Reconnect
• Authentication
• within webserver or standalone?
Scaling
Scaling

• Most likely, you want to work in async
  model for many stateful connections
Scaling

• Most likely, you want to work in async
  model for many stateful connections
• perl: AnyEvent / Twiggy
Scaling

• Most likely, you want to work in async
  model for many stateful connections
• perl: AnyEvent / Twiggy
• ruby: EventMachine
Scaling

• Most likely, you want to work in async
  model for many stateful connections
• perl: AnyEvent / Twiggy
• ruby: EventMachine
• python: tornado
WebSockets
 Packages
Perl

• Web::Hippie: AnyEvent and PSGI based
• Web::Hippie::Pipe: integrated message bus
  with AnyMQ
• Mojo
DEMO
Ruby

• em-websockets
• sunshower
• cramp
Others

• phpwebsockets
• Node.js
• Erlang
• Haskell
Thank you!
Bonus
HTML5 EventSource
 Content-Type: text/event-stream
 data: Foo
 id: 123

 data: Bar
 id: 124
  var eventSrc = new EventSource('events.php');
  
  eventSrc.addEventListener('open', function (event) {
    console.log(event.type);
  });
  
  eventSrc.addEventListener('message', function (event) {
    console.log(event.type);
    console.log(event.data);
  });

Websockets at tossug

  • 1.
    WebSockets and the Real-TimeWeb tossug 2010-07-06 Chia-liang Kao clkao@clkao.org
  • 2.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
    Outlines • comet server-pushtechnologies • websockets introductions • websockets examples • frameworks and packages supporting websockets
  • 13.
    Server-Push • browser tellsserver about interested information • information streamed from server to browser without explicit request
  • 16.
  • 17.
  • 18.
  • 19.
    Comet The word cometcame to English by way of the Latin word cometes. This word, in turn, came from the Greek word κόμη, which means "hair of the head". The Greek scientist and philosopher Aristotlefirst used the derived form of κόμη, κομήτης, to describe what he saw as "stars with hair." Theastronomical symbol for comets is (☄), consisting of a small disc with three hairlike extensions. • 2006, coined by Alex Russell • Server push for real time notification
  • 20.
    Widely used • gmail •plurk • facebook updates
  • 21.
    Comet - Long-poll •Browser connects to an event endpoint • connection idled when there’s no event • browser reconnects after receiving events
  • 22.
    Comet - ForeverIFrame • Makes use of browser incremental rendering • IE wants <br/> • Safari wants 1KB data • cross-iframe messaging
  • 23.
    Multi-part XHR • multi-part response with boundries: Content-Type: multipart/mixed; boundary=Foo --Foo Content-Type: application/json {foo: 1} --Foo Content-Type: application/json {foo: 2}
  • 24.
    Multi-part XHR • multi-part response with boundries: Content-Type: multipart/mixed; boundary=Foo --Foo Content-Type: application/json {foo: 1} --Foo Content-Type: application/json {foo: 2}
  • 25.
  • 26.
    Lots of hacks! •spinning “loading” indicator for FF and IE
  • 27.
    Lots of hacks! •spinning “loading” indicator for FF and IE • number of connections limits
  • 28.
    Lots of hacks! •spinning “loading” indicator for FF and IE • number of connections limits • transport overhead
  • 29.
    Lots of hacks! •spinning “loading” indicator for FF and IE • number of connections limits • transport overhead • webserver connections overhead
  • 30.
    Lots of hacks! •spinning “loading” indicator for FF and IE • number of connections limits • transport overhead • webserver connections overhead • ...... orz
  • 31.
  • 33.
  • 34.
  • 35.
    Websockets • HTML5 Websockets •Bidirectional communication over HTTP
  • 36.
    Websockets • HTML5 Websockets •Bidirectional communication over HTTP • Available in latest browsers
  • 37.
    Websockets • HTML5 Websockets •Bidirectional communication over HTTP • Available in latest browsers • or use http://github.com/gimite/web-socket-js
  • 38.
  • 39.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 40.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 41.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 42.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 43.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U
  • 44.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 45.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 46.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 47.
    Request: GET /demo HTTP/1.1 Host:example.com Connection: Upgrade Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 Sec-WebSocket-Protocol: sample Upgrade: WebSocket Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 Origin: http://example.com New in draft#76 ^n:ds[4U Response: HTTP/1.1 101 WebSocket Protocol Handshake Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Origin: http://example.com Sec-WebSocket-Location: ws://example.com/demo Sec-WebSocket-Protocol: sample 8jKS'y:G*Co,Wxa-
  • 48.
    my @keys =map { my $k = $env>{'HTTP_SEC_WEBSOCKET_KEY'.$_}; join('', $k =~ m/d/g) / scalar @{[$k =~ m/ /g]}; } (1,2); md5(pack('NN', @keys) . $key3);
  • 49.
  • 50.
  • 51.
    Websockets API ws =new WebSocket("ws://foo.com:5000”)); ws.onopen = function(ev) { ... } ws.onmessage = function(ev) { ... } ws.onclose = function(ev) { ... } ws.onerror = function(ev) { ... } ws.send(....);
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
    Session Management • Reconnect •Authentication • within webserver or standalone?
  • 57.
  • 58.
    Scaling • Most likely,you want to work in async model for many stateful connections
  • 59.
    Scaling • Most likely,you want to work in async model for many stateful connections • perl: AnyEvent / Twiggy
  • 60.
    Scaling • Most likely,you want to work in async model for many stateful connections • perl: AnyEvent / Twiggy • ruby: EventMachine
  • 61.
    Scaling • Most likely,you want to work in async model for many stateful connections • perl: AnyEvent / Twiggy • ruby: EventMachine • python: tornado
  • 62.
  • 63.
    Perl • Web::Hippie: AnyEventand PSGI based • Web::Hippie::Pipe: integrated message bus with AnyMQ • Mojo
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
    HTML5 EventSource Content-Type:text/event-stream data: Foo id: 123 data: Bar id: 124   var eventSrc = new EventSource('events.php');      eventSrc.addEventListener('open', function (event) {     console.log(event.type);   });      eventSrc.addEventListener('message', function (event) {     console.log(event.type);     console.log(event.data);   });

Editor's Notes

  • #11 show tradroom
  • #51 show web-socket-js and frontend code
  • #53 show firefox with web-socket-js
  • #62 show hippie timer and chatroom show hippie code