http://chenkangxian.iteye.com/blog/2268133
对于comet长连接来说,服务端如有内容需要发送给客户端时,服务端将原本占用的连接进行回复,此时原有的连接断开,重新发起长连接,直到服务端有内容响应。从每次消息发送到收到服务端消息应答,平均需要两次HTTP请求,一次请求将消息内容提交到服务端,另外还需保持一个长连接,当服务端有内容响应时,及时发回响应,可以通过一个简单的案例来进行介绍:
GET /testwebsocket/conn?cmd=revival&cid=c6e2f82f-edb1-4b61-ba68-0d5c65d92d5e&ram=0.95148686459288 HTTP/1.1
Host: www.bbb.com:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
Accept: */*
Referer: http://www.bbb.com:8080/testwebsocket/comet.htm
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 74
Date: Tue, 08 Dec 2015 12:19:40 GMT
上面是为了保证服务端通知能及时到达客户端,客户端发送给服务端的长连接请求头以及服务端响应给客户端的响应头,一次来回不计算消息体,头的大小为686byte。
下面是将消息内容发送给服务端所发送请求的请求头,以及服务端响应的响应头:
GET /testwebsocket/send.do?message=message HTTP/1.1
Host: www.bbb.com:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
Referer: http://www.bbb.com:8080/testwebsocket/comet.htm
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Tue, 08 Dec 2015 12:19:42 GMT
一次请求来回,不计消息体的大小,光是请求头及响应头,就占用了542byte。
换句话说,客户端给服务端发送一条消息,并且从服务端接收一次消息,总共要花费在请求头的代价是1228byte,而实际消息体的内容可能也并不大。
对于websocket来说,情况就不太一样了,websocket的浏览器端会先发送一个HTTP请求给服务端建立连接,服务端会回一个HTTP的响应,当连接建立好之后,浏览器端与服务端将通过frame的格式通信,中间附带的header信息几乎可忽略不计。
websocket建立连接的HTTP请求header:
GET /testwebsocket/websocket HTTP/1.1
Host: www.bbb.com:8080
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://www.bbb.com:8080
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Sec-WebSocket-Key: m9OzTVeeei/Hw12msI7jfw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
服务端回应的响应头:
HTTP/1.1 101 Switching Protocols
Server: Apache-Coyote/1.1
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: abEVNZcXPW+K1ptCD54EOh7xN0E=
Date: Tue, 08 Dec 2015 11:38:40 GMT
后续的通信,将直接是消息内容,额外附带信息几乎可忽略不计,那么第一次建立连接,将需要传输702byte(请求头与响应头)的数据,而后续的数据传输只跟消息本身相关。
那么,假设有如下三个场景,假设服务端每秒推送50条消息给前端用户,每条消息的长度为10byte,那么,对应不同的用户规模,客户端与服务端通信所传输的字节数如下:
1.假设同时在线人数为100人,采用comet长轮询方案服务端与客户端需要传输总的字节数=(50*(10+686))*100=3480kb,而采用websocket方式的话,服务端与客户端总共需要传输的字节数=(50*10+702)*100=75.2kb;
2. 假设同时在线人数为1000人,采用comet长轮询方案服务端与客户端需要传输总的字节数=(50*(10+686))* 1000=34800kb,而采用websocket方式的话,服务端与客户端总共需要传输的字节数=(50*10+702)*1000=752kb;
3. 假设同时在线人数为1w人,采用comet长轮询方案服务端与客户端需要传输总的字节数=(50*(10+686))*1w=348000kb,而采用websocket方式的话,服务端与客户端总共需要传输的字节数=(50*10+702)*1w=7520kb;
以上是对于服务端消息推送的场景,对于消息发送的场景以及comet的流方式的数据传输的性能对比类似,读者可参照上述方式自行计算