SPDY 的要求是
• 改善 Page load time 網⾴頁載⼊入時間
• 保持 HTTP/1.1 語義 ,包括:
• HTTP methods
• Status Codes
• URIs
• Headers fields
• 這樣只要升級 Web Server 和 Browser 即可,
應⽤用程式不需要改
48
... we’re not replacing all of HTTP — the
methods, status codes, and most of the
headers you use today will be the same.
Instead, we’re re-defining how it gets used “on
the wire” so it’s more efficient, and so that it
is more gentle to the Internet itself ....
- Mark Nottingham (chair, HTTPBis Working Group)
49
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
SYN_REPLY 1
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1
SYN_REPLY 1
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN
Data 1
SYN_REPLY 1
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1
SYN_REPLY 1
close
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1
SYN_REPLY 1
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1
SYN_REPLY 1
Data 2
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1
SYN_REPLY 1
Data 2 + FIN
Data 2
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1 Data 3
SYN_REPLY 1
Data 2 + FIN
Data 2
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
SYN_STREAM 5
Data 1 + FIN SYN_REPLY 3
Data 1 Data 3
SYN_REPLY 1
Data 2 + FIN Data 3 + FIN
Data 2
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
可以同時平⾏行發 Request
SYN_STREAM 5
在⼀一條 TCP Connection 上
Data 1 + FIN SYN_REPLY 3
Data 1 Data 3
SYN_REPLY 1
Data 2 + FIN Data 3 + FIN
Data 2
close SYN_REPLY 5
69
Client Server
open
SYN_STREAM 1
SYN_STREAM 3
可以同時平⾏行發 Request
SYN_STREAM 5
在⼀一條 TCP Connection 上
Data 1 + FIN SYN_REPLY 3 Frames 可以混雜交錯
Data 1 Data 3 有 Stream ID 可以識別
SYN_REPLY 1
Data 2 + FIN Data 3 + FIN
Data 2
close SYN_REPLY 5
69
const unsigned char SPDY_dictionary_txt[] = {
! 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, - - - - o p t i
SPDY/3
! 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, o n s - - - - h
! 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, e a d - - - - p
! 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, o s t - - - - p
Lookup ! 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, u t - - - - d e
! 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, l e t e - - - -
! 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, t r a c e - - -
dictionary!
!
!
0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74,
0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65,
0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73,
0x00,
0x70,
0x65,
-
-
t
a
-
-
c
-
c
c
a
h
e
c
a
p
c
r
t
e
s
-
p
e
! 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, t - - - - a c c
! 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, e p t - e n c o
! 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, d i n g - - - -
! 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, a c c e p t - l
! 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, a n g u a g e -
! 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, - - - a c c e p
! 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, t - r a n g e s
! 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, - - - - a g e -
! 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, - - - a l l o w
! 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, - - - - a u t h
! 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, o r i z a t i o
! 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, n - - - - c a c
! 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, h e - c o n t r
! 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, o l - - - - c o
! 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, n n e c t i o n
! 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, - - - - c o n t
! 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, e n t - b a s e
! 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, - - - - c o n t
! 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, e n t - e n c o
! 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, d i n g - - - -
! 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, c o n t e n t -
! 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, l a n g u a g e
! 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, - - - - c o n t
! 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, e n t - l e n g
! 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, t h - - - - c o
! 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, n t e n t - l o
! 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, c a t i o n - -
! 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - - c o n t e n
! 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, t - m d 5 - - -
! 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - c o n t e n t
! 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, - r a n g e - -
http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3
! 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 75
0x65, 0x6e, - - c o n t e n
! 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, t - t y p e - -
不是即時聊天室⽤用的那個
Server Push
• 不是 Comet
• 不是 Ajax Long Polling
• 不是 Web Socket
85
情境:
拿到 HTML 後,還需要再發 Request
拿 CSS, JS, Images 網⾴頁才能載⼊入完成
Client Server
open Request HTML
HTML
CSS
JS
Image
Image
86
情境:
拿到 HTML 後,還需要再發 Request
拿 CSS, JS, Images 網⾴頁才能載⼊入完成
Client Server
open Request HTML
HTML
有沒有辦法在⼀一個
RTT 就從 Server 拿
CSS 到全部的資料呢?
JS
Image
Image
86
⺫⽬目前的 HTTP 就有 work around 了
Inline Resource
當 CSS, JS 很⼩小時,Inline 進 HTML
<html> <html>
<head> <head>
<style> <script type="text/javascript">
.yellow {background-color: yellow;} /* contents of a small JavaScript file */
.blue {color: blue;} </script>
.big { font-size: 8em; } </head>
.bold { font-weight: bold; } <body>
</style> <div class="blue yellow big bold">
</head> Hello, world!
<body> </div>
<div class="blue yellow big bold"> </body>
Hello, world! </html>
</div>
</body>
</html>
https://developers.google.com/speed/docs/mod_pagespeed/filter-css-inline
87
Inline Resource with
Data URI
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">
ul.checklist li.complete {
padding-left: 20px;
background: white url('data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l
EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6
P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;
}
window.open('data:text/html;charset=utf-8,%3C%21DOCTYPE%20' +
'html%3E%0D%0A%3Chtml%20lang%3D%22en%22%3E%0D%0A%3Chead%' +
'3E%3Ctitle%3EEmbedded%20Window%3C%2Ftitle%3E%3C%2Fhead%' +
'3E%0D%0A%3Cbody%3E%3Ch1%3E42%3C%2Fh1%3E%3C%2Fbody%3E%0A' +
'%3C%2Fhtml%3E%0A%0D%0A','_blank','height=300,width=400');
http://en.wikipedia.org/wiki/Data_URI_scheme
88
Inline Resource 的缺點
• 沒辦法 Cache :(
• Data URI 會增加實際檔案⼤大⼩小
(不壓縮的話約增加 1/3,雖然網⾴頁會 gzip,但畢竟還是增加⼤大⼩小)
• 增加 coding 複雜性
89
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
CSS
Image
Image
Image
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Image
Image
Image
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Push Image
Image
Image
Image
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Push Image
Image
Push Image
Image
Image
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Push Image
Image
Push Image
Image
Push Image
Image
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Push Image
Image
Push Image
Image
Push Image
Image
最後 Push HTML
HTML
close
90
SPDY’s Server Push
把東⻄西從 Server 推到瀏覽器的 Cache Store
Client Server
open Request HTML
Push CSS
CSS
Push Image
Image
Push Image
Image
Push Image
Image
最後 Push HTML
HTML
close
進階發揮: Push 下⼀一⾴頁 HTML 或 client-side template 等
90
SPDY How?
• SPDY 的 Web Server 可以主動發 Stream
給 Client
• Streams 除了是 multiplexed,也是雙向
的,不需要多開 TCP Connection
92
SPDY How?
• SPDY 的 Web Server 可以主動發 Stream
給 Client
• Streams 除了是 multiplexed,也是雙向
的,不需要多開 TCP Connection
• 從 Client 發的 stream-id 是奇數,從
Server 發的 stream-id 是偶數
92
Server Push Demo
Example
(Apache mod_spdy + Rails)
CSS, JS, Images
從瀏覽器 Cache 拿
93
Server ⽀支援性如何?
• Web Server
• Apache mod_spdy
• ⽤用 X-Associated-Content Header
• Nginx SPDY patch 不⽀支援
• Application Server
• node-spdy
• Jetty
94
mod_spdy 的
Server Push 流程
1. Request HTML 2. Request HTML
Web App
Client
4. CSS Server Server
Image 3.
Image HTML
Image
加上
HTML X-Associated-Content Header:
“https://foobar.org/app.css”,
”https://foobar.org/image1.png”
”https://foobar.org/image2.png”
”https://foobar.org/image3.png”
95
Sample code at Rails
class
WelcomeController
<
ApplicationController
def
server_push
response.headers["X-‐Associated-‐Content"]
=
'"https://www.ihower.tw/assets/application.css":0,
"https://www.ihower.tw/assets/application.js":1,
"https://www.ihower.tw/assets/flags/Taiwan.png":2,
"https://www.ihower.tw/assets/flags/Afghanistan.png":3,
"https://www.ihower.tw/assets/flags/Kenya.png":4'
end
end
96
Server Push 點評
• Server 不知道 Client 是不是已經有快取
了,如果已經有了⼜又 push 就浪費了
• 實務上⼀一個最簡單的⽅方式就是只讓第⼀一
個 stream 做 server push
• 需要 Application 層細節的調教
97
SPDY is not HTTP 2.0
yet
• 還沒定案
• SPDY 只是討論的起點
• Header 壓縮演算法 ?
• DNS name resolution push ?
• cert data push (節省SSL handshake 時間) ?
• explicit proxy support ?
99
It’s important to understand that SPDY isn’t
being adopted as HTTP/2.0; rather, that it’s
the starting point of our discussion, to avoid
a laborious start from scratch.
- Mark Nottingham (chair, HTTPBis Working Group)
100
HTTP/2.0 @ HTTPbis Working Group 2012
http://tools.ietf.org/agenda/83/slides/slides-83-httpbis-6.pdf
101
HTTP/2.0 @ HTTPbis Working Group 2012
http://tools.ietf.org/agenda/83/slides/slides-83-httpbis-6.pdf
102