Websocket

42
11年10月28日星期五

Transcript of Websocket

Page 1: Websocket

11年10月28日星期五

Page 2: Websocket

The way to HTML5

11年10月28日星期五

Page 3: Websocket

The way to HTML5

—— websocket 协议介绍与实现

孟红伦

2011-10

11年10月28日星期五

Page 4: Websocket

FD们常写这样的代码:

⼀一、前言

11年10月28日星期五

Page 5: Websocket

$.ajax(‘http://localhost/do_sth/’,{ ‘type’:‘GET’, ‘dataType’:‘json’, ‘success’:function(data){ console.log(data); } });

FD们常写这样的代码:

⼀一、前言

11年10月28日星期五

Page 6: Websocket

以后还会写这样的代码:⼀一、前言

11年10月28日星期五

Page 7: Websocket

var ws_uri = "ws://localhost:9999"; if ("WebSocket" in window) { webSocket = new WebSocket(ws_uri); }else if("MozWebSocket" in window) { // Firefox 7/8 webSocket = new MozWebSocket(ws_uri); } webSocket.onmessage = function(e) { console.log("Got echo: " + e.data); }

以后还会写这样的代码:⼀一、前言

11年10月28日星期五

Page 8: Websocket

我们能看懂此图中的大部分东西⼀一、前言

11年10月28日星期五

Page 9: Websocket

⼀一、前言

11年10月28日星期五

Page 10: Websocket

看懂这些 HTTP 相关的信息,是我们平时工作中 debug, WPO 等必须的。

⼀一、前言

11年10月28日星期五

Page 11: Websocket

看懂这些 HTTP 相关的信息,是我们平时工作中 debug, WPO 等必须的。

WebSocket 做为一个新的协议,自然和 HTTP 有较大区别,我们的知识也需要同步更新了。

⼀一、前言

11年10月28日星期五

Page 12: Websocket

看懂这些 HTTP 相关的信息,是我们平时工作中 debug, WPO 等必须的。

那么 new WebSocket(ws_uri) 的背后发生了什么呢?

WebSocket 做为一个新的协议,自然和 HTTP 有较大区别,我们的知识也需要同步更新了。

⼀一、前言

11年10月28日星期五

Page 13: Websocket

接下来我们一起来窥探 WebSocket protocol 的细节,并且根据 protocol 实现一个简单的 WebSocket server

⼀一、前言

11年10月28日星期五

Page 14: Websocket

二、WebSocket API

11年10月28日星期五

Page 15: Websocket

二、WebSocket API

依据API的定义,我们可以写出一段非常简单的浏览器端的 WebSocket 代码:

11年10月28日星期五

Page 16: Websocket

二、WebSocket API

依据API的定义,我们可以写出一段非常简单的浏览器端的 WebSocket 代码:

var ws_uri = "ws://localhost:9999"; webSocket = new WebSocket(ws_uri); webSocket.onmessage = function(e) { console.log("Got echo: " + e.data); }

11年10月28日星期五

Page 17: Websocket

二、WebSocket API

很简单,对吧,不过我们今天的重点不是WebSocket API,而是 WebSocket Protocol。

11年10月28日星期五

Page 18: Websocket

三、WebSocket Protocol

现在还处于草案阶段,一直在变化,我们拿草案10,这个 chrome 14+ , firefox 7+ 采用的版本来讲解。

chrome blog 里说这是一个比较稳定的版本,以后不会再有重大更新了。

11年10月28日星期五

Page 19: Websocket

三、WebSocket Protocol

现在还处于草案阶段,一直在变化,我们拿草案10,这个 chrome 14+ , firefox 7+ 采用的版本来讲解。

chrome blog 里说这是一个比较稳定的版本,以后不会再有重大更新了。

11年10月28日星期五

Page 20: Websocket

三、WebSocket Protocol

overview:

协议主要分为两个部分:握手和数据传输。

握手完毕,才开始数据传输的过程。

数据在应用层都表现成“消息”的形式,所以我们在 API 中可以看到 onmessage 这种事件驱动的API。

11年10月28日星期五

Page 21: Websocket

三、WebSocket Protocol

overview:

在网络层,数据是以 frame 的形式存在的,每个 frame 并不和应用层的 message 直接对应。有的 frame 不会产生 message ,也有可能几个 frame 合并起来组成一个 message

11年10月28日星期五

Page 22: Websocket

三、WebSocket Protocol

overview:

frame 的定义是 WebSocket Protocol 中的重点,直接决定了我们应该发送什么样的 raw data, 接收到 raw data 后,应该怎么转换成 message 或者 执行响应的动作 ( control frame )

11年10月28日星期五

Page 23: Websocket

三、WebSocket Protocol

HandShake:

11年10月28日星期五

Page 24: Websocket

三、WebSocket Protocol

HandShake:

浏览器端通过 GET 方式请求 WebSocket 服务器, HTTP Header 中包含 origin , WebSocket Version , WebSocket Key , Cookies 等信息

Connection: UpgradeUpgrade: websocket 标识这是要请求 WebSocket

11年10月28日星期五

Page 25: Websocket

三、WebSocket Protocol

HandShake:

服务器端,需要返回 HTTP/1.1 101 Switching Protocols 表示要切换协议。原样返回Connection: UpgradeUpgrade: websocket表示要升级到 websocket 协议

11年10月28日星期五

Page 26: Websocket

三、WebSocket Protocol

HandShake:

返回 Sec-WebSocket-Protocol: chat表示接受此 subprotocol

下面是为关于安全的

11年10月28日星期五

Page 27: Websocket

三、WebSocket Protocol

HandShake:

请求头里的 Sec-WebSocket-Origin: http://work是帮助 server 验证是否为合法域

11年10月28日星期五

Page 28: Websocket

三、WebSocket Protocol

HandShake:

请求头里的 Sec-WebSocket-Origin: http://work是帮助 server 验证是否为合法域

Sec 开头的 HTTP Header 是无法通过 javascript 直接设置的

11年10月28日星期五

Page 29: Websocket

三、WebSocket Protocol

HandShake:

最后,server 需要向 client 证明它确实收到了来自 client 的 websocket hankshake,阻止可能通过 XHR 或者 form 提交的方式伪造的请求。

11年10月28日星期五

Page 30: Websocket

三、WebSocket Protocol

HandShake:为了证明这些,server 需要获得 HandShake 的 HTTP header 中的Sec-WebSocket-key, 去掉头尾空格,和 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 这个字符串拼接起来,先做一次 SHA-1 hash ,再做一次 base64-encode , 然后在Response Header 中的“Sec-WebSocket-Accept”输出此值

11年10月28日星期五

Page 31: Websocket

三、WebSocket Protocol

HandShake:

到这里,就握手成功,进入 WebSocket 数据传输阶段。

我们来看处理握手的 Python 代码

git checkout handshake

11年10月28日星期五

Page 32: Websocket

三、WebSocket Protocol

frame的定义 :

11年10月28日星期五

Page 33: Websocket

三、WebSocket Protocol

frame的定义 :

11年10月28日星期五

Page 34: Websocket

三、WebSocket Protocol

FIN:1bit,标识是否为 message 的最后一帧

RSV0,RSV1,RSV2:每个1bit, 只有在有扩展的情况下,才会出现非0的值

opcode: 4bit, 定义如何解释 payload data

frame的定义 :

11年10月28日星期五

Page 35: Websocket

三、WebSocket Protocol

FIN:1bit,标识是否为 message 的最后一帧

RSV0,RSV1,RSV2:每个1bit, 只有在有扩展的情况下,才会出现非0的值

opcode: 4bit, 定义如何解释 payload data

frame的定义 :

11年10月28日星期五

Page 36: Websocket

三、WebSocket Protocol

FIN:1bit,标识是否为 message 的最后一帧

RSV0,RSV1,RSV2:每个1bit, 只有在有扩展的情况下,才会出现非0的值

opcode: 4bit, 定义如何解释 payload data

frame的定义 :

opcode 的定义: * %x0 denotes a continuation frame

* %x1 denotes a text frame

* %x2 denotes a binary frame

* %x3-7 are reserved for further non-control frames

* %x8 denotes a connection close

* %x9 denotes a ping

* %xA denotes a pong

* %xB-F are reserved for further control frames

11年10月28日星期五

Page 37: Websocket

三、WebSocket Protocol

mask: 1bit ,定义 payload data 是否有伪装,如果为1,就存在 masking-key 用来解码,客户端发往服务器端的数据,必须为1

payload length: 7 bits , 7+16bits , or 7+64 bits 。前7bit如果值为 0 -125 之间,则它就表示所载数据长度,如果为 126,接下来的 2byte 用来表示长度,如果为 127,接下来的 4byte 用来表示长度。

Masking-Key: 0 or 4 bytes. mask 为0 ,则key的长度为 0 ,如果 mask 为 1, key 占用 4 bytes

frame的定义 :

11年10月28日星期五

Page 38: Websocket

三、WebSocket Protocol

Payload data: (x+y)bytes , payload data 包含扩展数据和应用数据

Extension data: x bytes, 一般为0,除非有扩展存在

Application data: y bytes , 长度等于 payload data 的长度减去扩展的长度。扩展必须定义怎么计算它自己的长度。

frame的定义 :

11年10月28日星期五

Page 39: Websocket

三、WebSocket Protocol

frame的定义 :

浏览器已经封装好了 WebSocket 客户端,那我们先来实现一个简单的 server,解析浏览器发送过来的消息。

最后再尝试封装 frame 发往前端

11年10月28日星期五

Page 42: Websocket

Q&A

11年10月28日星期五