The realtime web: HTTP/1.1 to WebSocket, SPDY and beyond Guillermo - - PowerPoint PPT Presentation

the realtime web http 1 1 to websocket spdy and beyond
SMART_READER_LITE
LIVE PREVIEW

The realtime web: HTTP/1.1 to WebSocket, SPDY and beyond Guillermo - - PowerPoint PPT Presentation

The realtime web: HTTP/1.1 to WebSocket, SPDY and beyond Guillermo Rauch @ QCon . November 2012. Guillermo . CTO and co-founder at LearnBoost . Creator of socket.io and engine.io . @ rauchg on twitter http:// devthought.com Author of Wileys


slide-1
SLIDE 1

The realtime web: HTTP/1.1 to WebSocket, SPDY and beyond

Guillermo Rauch @ QCon. November 2012.

slide-2
SLIDE 2

Guillermo.

slide-3
SLIDE 3

CTO and co-founder at LearnBoost.

slide-4
SLIDE 4

Creator of socket.io and engine.io.

slide-5
SLIDE 5

@rauchg on twitter

slide-6
SLIDE 6

http://devthought.com

slide-7
SLIDE 7

Author of Wiley’s Smashing Node

http://smashingnode.com

slide-8
SLIDE 8

The realtime web

slide-9
SLIDE 9

HTTP over TCP/IP

slide-10
SLIDE 10

No specific techniques or protocols

slide-11
SLIDE 11

Realtime = fast data exchange.

slide-12
SLIDE 12

Let's analyze the timeline of a typical web request.

slide-13
SLIDE 13

https://mywebsite.com

slide-14
SLIDE 14
  • 1. We first need to look up the DNS record for mywebsite.com
slide-15
SLIDE 15
  • DNS. Low bandwidth. Potentially high latency.
slide-16
SLIDE 16

Browsers have different approaches and optimizations.

slide-17
SLIDE 17

Our best shot at optimizing this is <link rel="dns-prefetch">.

slide-18
SLIDE 18
  • 2. http vs https.
slide-19
SLIDE 19

“In January this year (2010), Gmail switched to using HTTPS for everything by default […] In our production frontend machines, SSL/TLS accounts for less than 1% of the CPU load, less than 10KB of memory per connection and less than 2% of network overhead.”

http://www.imperialviolet.org/2010/06/25/overclocking-ssl.html (emphasis mine)

slide-20
SLIDE 20

SSL allows us to upgrade the protocol without breaking

  • utdated proxies (eg: WebSocket).
slide-21
SLIDE 21
  • 3. Request headers
  • 1. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  • 2. Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
  • 3. Accept-Encoding:gzip,deflate,sdch
  • 4. Accept-Language:en-US,en;q=0.8
  • 5. Cache-Control:max-age=0
  • 6. Connection:keep-alive
  • 7. Host:www.imperialviolet.org
  • 8. If-Modified-Since:Tue, 06 Nov 2012 21:22:53 GMT
  • 9. User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17
slide-22
SLIDE 22

Consider a character-by-character realtime editor (GDocs).

slide-23
SLIDE 23

In the following example we send the character “a”.

slide-24
SLIDE 24
  • 1. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  • 2. Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
  • 3. Accept-Encoding:gzip,deflate,sdch
  • 4. Accept-Language:en-US,en;q=0.8
  • 5. Cache-Control:max-age=0
  • 6. Connection:keep-alive
  • 7. Host:www.myhost.com
  • 8. User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17
  • 1. { “c”: “a” }

Headers Body (JSON obj)

slide-25
SLIDE 25

HTTP/1.1 overhead: 370~ bytes per character. Boo.

slide-26
SLIDE 26

This only considers sending data.

slide-27
SLIDE 27

How ‘bout getting data?

slide-28
SLIDE 28

We poll the server through a GET request

slide-29
SLIDE 29

When the server responds, we send another one.

slide-30
SLIDE 30

And another one.

slide-31
SLIDE 31

…and another one. Boo.

slide-32
SLIDE 32

If the server has no data to send us, we would be generating a LOT of traffic.

slide-33
SLIDE 33

Instead, we make the server wait a bit if it has no data.

slide-34
SLIDE 34

This is what we call long-polling.

slide-35
SLIDE 35

Pseudo-code time.

slide-36
SLIDE 36

function send(data){ var xhr = new XMLHttpRequest(); xhr.open(‘POST’, ‘/’, false); xhr.send(data); } function get(fn) { var xhr = new XMLHttpRequest(); xhr.open(‘GET’, ‘/’, false); xhr.send(data); xhr.onreadystatechange = function(){ if (200 == xhr.status) { fn(); // send data to user get(); // restart poll } } }

slide-37
SLIDE 37

Most applications need to send data in a particular order.

slide-38
SLIDE 38

For our example, the order that the user types.

slide-39
SLIDE 39

Therefore, to replicate socket semantics we need to implement buffering. Boo.

slide-40
SLIDE 40

For example, the user types a then b c d every 100ms.

slide-41
SLIDE 41

If an existing send() is in-flight…

slide-42
SLIDE 42

We accumulate the other data packets in an array.

slide-43
SLIDE 43

Then we send that over when the server replies.

slide-44
SLIDE 44

But instead of just sending one request per character.

slide-45
SLIDE 45

We try to create a data packet with “b” “c” and “d” to minimize the request headers traffic.

slide-46
SLIDE 46
  • 1. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  • 2. Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
  • 3. Accept-Encoding:gzip,deflate,sdch
  • 4. Accept-Language:en-US,en;q=0.8
  • 5. Cache-Control:max-age=0
  • 6. Connection:keep-alive
  • 7. Host:www.myhost.com
  • 8. User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.5 Safari/537.17
  • 1. [{ “c”: “b” }, { “c”: “c” }, { “c”: “d” }]

Headers Body (JSON Array)

slide-47
SLIDE 47

This means, however, that we need a protocol.

slide-48
SLIDE 48

A protocol on top of a protocol (HTTP).

slide-49
SLIDE 49

Server and client need to agree that the data is not simply the request body, but within it.

slide-50
SLIDE 50

This is a lot of work before you can focus on your app!

slide-51
SLIDE 51

This has been a common trend in web development.

slide-52
SLIDE 52

Need rounded corners?

slide-53
SLIDE 53

<div class=”wrap-outer”> <div class=”wrap”> <div class=”wrap-inner”> <div class=”content”> </div> </div> </div> </div>

Circa 2001

.wrap-outer { background: …; padding: …; } .wrap { background: …; padding: …; } .wrap-inner { background: …; padding: …; }

slide-54
SLIDE 54

<div class=”content”> </div>

Now

.content { border-radius: 3px; }

slide-55
SLIDE 55

For the realtime web…

slide-56
SLIDE 56

Circa 2001

  • Data buffering on server within GET polls.
  • Data buffering on client.
  • JSON protocol or equivalent.
  • XMLHttpRequest fallbacks
  • Cross-domain tricks
slide-57
SLIDE 57

Now

  • WebSocket!
slide-58
SLIDE 58

Simpler client side API.

slide-59
SLIDE 59

var ws = new WebSocket(); ws.onopen = function(){}; ws.onclose = function(){}; ws.onmessage = function(){};

slide-60
SLIDE 60

Light-weight protocol.

slide-61
SLIDE 61

Instead of sending many HTTP requests.

slide-62
SLIDE 62

Browser sends one that contains a header: Upgrade: WebSocket

slide-63
SLIDE 63

The connection is then taken over.

slide-64
SLIDE 64

Like TCP but unlike HTTP , it’s bi-directional.

slide-65
SLIDE 65

We can send and receive over the same socket.

slide-66
SLIDE 66

In terms of our realtime app example…

slide-67
SLIDE 67

WebSocket overhead: 2-5~* bytes per character.

* depending on spec

slide-68
SLIDE 68

But WS is buggy on mobile, unavailable in older browsers, not understood by all middleware, breaks often without SSL.

slide-69
SLIDE 69

Meet engine.io, the data transport engine of socket.io

slide-70
SLIDE 70

var ws = new eio.Socket(); ws.onopen = function(){}; ws.onclose = function(){}; ws.onmessage = function(){};

slide-71
SLIDE 71

Same API, long-polling first, upgrades to WS if possible.

slide-72
SLIDE 72

The main advantage of WS is lightweight framing!

slide-73
SLIDE 73

Most of the benefits that WS offers, like lower-bandwidth, would still benefit XMLHttpRequest.

slide-74
SLIDE 74

Meet SPDY.

slide-75
SLIDE 75

Headers overhead?

slide-76
SLIDE 76

“SPDY compresses request and response HTTP headers, resulting in fewer packets and fewer bytes transmitted.”

http://www.chromium.org/spdy/spdy-whitepaper

slide-77
SLIDE 77

TCP overhead?

slide-78
SLIDE 78

“SPDY allows for unlimited concurrent streams over a single TCP connection.”

http://www.chromium.org/spdy/spdy-whitepaper

slide-79
SLIDE 79

SPDY works transparently to your app.

slide-80
SLIDE 80

SPDY assumes SSL.

slide-81
SLIDE 81

Just upgrade your SSL terminator or load balancer and reap the benefits!

slide-82
SLIDE 82

In other words, if you host your app on Heroku…

slide-83
SLIDE 83

Keep doing what you’re doing, and wait for the upgrade.

slide-84
SLIDE 84

But wait, many apps still need socket-like semantics.

slide-85
SLIDE 85

I want to write “socket.send(‘data’);” instead of “new XMLHttpRequest”

slide-86
SLIDE 86

I’m not even sending XML!@!!@

slide-87
SLIDE 87

Solution: WebSocket layering over SPDY/3.

slide-88
SLIDE 88

“With this protocol, WebSocket API get both benefits of usable bi-directional communication API, and a fast, secure, and scalable multiplexing mechanism on the top of SPDY”

https://docs.google.com/document/d/1zUEFzz7NCls3Yms8hXxY4wGXJ3EEvoZc3GihrqPQcM0/edit#

slide-89
SLIDE 89

Currently a draft.

slide-90
SLIDE 90

SPDY/3 is currently experimental and available through chrome://flags.

slide-91
SLIDE 91

Solution until the ideal world occurs: engine.io

slide-92
SLIDE 92

Moving forward… Most applications are not data-packet

  • riented.
slide-93
SLIDE 93

socket.io builds on top of engine.io to offer easy-to-use realtime events for everyone.

slide-94
SLIDE 94

var socket = io.connect(); socket.on(‘character’, function(){ // render! }); socket.on(‘chat message’, function(){ // render! }); socket.emit(‘ready!’);

slide-95
SLIDE 95

The goal is to not just focus on the speed of data transfer but also speed of development.

slide-96
SLIDE 96

While ensuring the reliability that the data can be exchanged in the fastest way, in every network, on every device.

slide-97
SLIDE 97

What’s next?

slide-98
SLIDE 98
  • Raw TCP/UDP sockets?
slide-99
SLIDE 99

chrome.experimental.socket.create('tcp', '127.0.0.1', 8080, function(socketInfo) { chrome.experimental.socket.connect(socketInfo.socketId, function (result) { chrome.experimental.socket.write(socketInfo.socketId, "Hello, world!"); }); });

slide-100
SLIDE 100

For now, only for extensions.

slide-101
SLIDE 101
  • Removing the server out of the equation.
slide-102
SLIDE 102

WebRTC PeerConnection.

slide-103
SLIDE 103

Currently called “webkitDeprecatedPeerConnection”

slide-104
SLIDE 104

Let’s be patient!

slide-105
SLIDE 105

The end.