轮询(短连接)与长连接都是基于http协议,而web socket是web端通过http与服务器端建立tcp连接成功后抛弃http保持tcp连接。
1.轮询:专门建立一个轮询请求的接口,里面只保留一个任务id,只需要发送任务id,就可以获取当前任务的情况。如果返回了结果,轮询结束,没有返回则等待一会儿,继续发送请求。
2.长连接:http分为长连接与短连接,http默认使用短连接,长连接是指客户端发送http请求给服务器端,服务器端保持这个连接。
客户端在http请求头中加入Connection:Keep-alive,告诉服务器端http由短连接升级为长连接。
3.web socket:由于以上两种均无法实现由服务器端主动向客户端推送信息,所以web socket就诞生了,首先我们要知道socket并不是一个类似http,ftp的协议,socket是套接字,我把他理解为基于tcp的接口。
我们都知道tcp协议有3次握手和第四次挥手,web socket就是采用http协议与服务器端进行握手,
首先我们来看个典型的Websocket握手(借用Wikipedia的。。)
(request)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
相比于普通的http请求,web socket的请求报文中多了一些东西。
Upgrade:websocket
Connection:Upgrade
这两句话告诉服务器,客户端发起的是websocket请求而不是普通的http请求(用于升级http协议)Sec-WebSocket-Key:
Sec-WebSocket-Key:x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
首先Sec-WebSocket-Key是一个Base64 encode的值,是有浏览器随机生成的,用于验证是否真的websocket
Sec-WebSocket-Protocol是用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。最后
Sec-WebSocket-Version是告诉服务器所使用的websocket协议的版本如:http 1.1|http 2.0
然后服务器会返回(response):
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Upgrade:websocket
Connection:Upgrade
告诉客户端即将升级websocket协议
Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key。
以下是基于go语言的解析加密Sec-WebSocket-Key的伪代码。
var keyGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
func computeAcceptKey(challengeKey string) string {
h := sha1.New()
h.Write([]byte(challengeKey))
h.Write(keyGUID)
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
type digest struct {
h [5]uint32
x [chunk]byte
nx int
len uint64
}
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
func (d *digest) Reset() {
d.h[0] = init0
d.h[1] = init1
d.h[2] = init2
d.h[3] = init3
d.h[4] = init4
d.nx = 0
d.len = 0
}
后面的,Sec-WebSocket-Protocol 则是表示最终使用的协议。
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈