您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页WebSocket

WebSocket

来源:二三娱乐

在H5,js代码新增了WebSocket的API。这玩意儿,从使用上来说,不难,也就onopen、onclose、onmessage、onerror这几个接口而已,前段时间使用的时候,就还是不由自主地去看一些这方面的东西。

Websocket是基于TCP协议上实现的,也有借助HTTP协议,但与HTTP1.X协议不同地方是,WebSocket是长连接,双方只需要一个握手动作(这里是借助HTTP协议),就可以建立一条连接通道,接着就能相互传输数据了;而HTTP1.X是短连接的,每次发起请求都要在TCP层来个3次握手,数据传输完或到指定的超时时间后就断开连接,若要多次请求,就要不断发起请求,这样挺占带宽。
Websocket在服务器方面,只需增加支持即可,如Python的tornado框架就支持,golang也挺多的,但我用的是大猩猩:gorilla。web服务器上,nginx在1.3.13版本也支持;其他web server,自行去搜索吧。浏览器方面除了老IE系,其他浏览器目前的新版本基本都支持WebSocket。

Javascript的接口

var conn = new WebSocket("ws://ip:port/");
conn.onclose = function(evt) {
    console.log(evt);
}

conn.onmessage = function(evt) {
    console.log(evt);
}

conn.onopen = function(evt) {
    console.log(evt);
}

conn.onerror = function(evt) {
    console.log(evt);
}

各接口看名称就知道是什么意思了。
浏览器与服务端建立连接的时候,要经过一个Websocket握手协议

GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 172.16.1.11
Origin: 
Sec-WebSocket-Key: BVuKSx8KJKN2VAGM0i6gjw==
Sec-WebSocket-Version: 13

这是正常的HTTP的GET请求,然后在请求头里增加了

Upgrade: websocket
Connection: Upgrade

这等于告诉web服务器,发起的请求是Websocket协议的,要用Websocket协议方式来处理请求。

在请求头里,还增加了

Sec-WebSocket-Key: BVuKSx8KJKN2VAGM0i6gjw==

看值的话,就应该能猜到,是通过BASE64编码而成的值,这是浏览器随机生成的。

HTTP响应头
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: sr0Tsn4bYggO1mzRZHpiOQO+FYE=

Sec-WebSocket-Accept这个是通过服务器确认,并加密后的Sec-WebSocket-Key。下面的这个响应头代表告诉客户端,升级成Websocket协议,属于HTTP最后负责地方

Upgrade: websocket
Connection: Upgrade

为什么说是HTTP最后负责的地方?因为WebSocket只是借助了HTTP协议去握手,仅此而已。此后信息通讯时,并不基于HTTP协议,而是基于更底层的TCP协议。WebSocket是一个和HTTP协议一样是基于TCP协议上的应用层协议。

数据收发

Websocket是可以发数据类型消息,也可以发控制类型消息。
数据类型消息包含:纯文本消息,二进制消息
控制类型消息包含:Ping,Pong,Close

更准确的说,WebSocket消息传输包含数据帧和控制帧,控制帧包含Ping,Pong,Close

这3个帧的Opcode各不相同:
  1. Ping帧的Opcode是9,0x09
  2. Pong帧的Opcode是10,0x0A
  3. Close帧的Opcode是8,0x08
数据帧包含文本帧和二进制帧
  1. 文本帧的Opcode是1,0x01
  2. 二进制帧的Opcode是2,0x02

还有一个既非数据帧,也非控制帧,是0x00,代表继续帧。
通过上面几个数字看到,还缺了几个数字,这几个缺了的数字是协议保留,以备后用。

保留帧
  1. 0x03——0x07:保留用于未来的非控制帧
  2. 0x0B——0x0F:保留用于未来的控制帧
ping帧的数据传输
ping

可以看到opcode是数字9

pong帧的数据传输
pong

可以看到opcode是数字10

close帧
92701058-92E0-4E07-AFDA-2F394CD66CF1.png

在js的接口中,没有主动发起ping接口的调用,这一般是在服务器那发起ping请求,浏览器接收到ping帧后,就会回个pong帧,从而达到心跳效果。

发送文本数据

从web界面向服务器发送32个‘f’,截取传输数据如下图:


C4B0F5CA-49D3-4F27-8193-ABA7A52DB91D.png

其他

之前在网上无意间看到这图,觉得挺不错的,描述建立连接时,websocket和TCP层的握手关系,很一目了然


handshake

在建立建立之后,每次端对端之间发送数据,另一端在TCP层都会回发个ACK表示确认。
WebSocket只是个协议,不是只能运行在浏览器上,自行用手机/其他客户端也可以实现,只需遵循协议即可(目前协议文档是RFC6455),个人觉得,假如没有其他更好想法,用这个协议来代替很多TCP层的数据传输格式也是不错的。

还有一个是IBM公司搞的MQTT协议,之前了解过其主要用于嵌入式设备,说是比较省电(相对于HTTP协议来比较那的确是),使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。它跟Websocket一样也是基于TCP协议的,都有各自的协议头格式。

Copyright © 2019- yule263.com 版权所有 湘ICP备2023023988号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务