Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

websocket #37

Open
ronghaoZHI opened this issue May 14, 2020 · 0 comments
Open

websocket #37

ronghaoZHI opened this issue May 14, 2020 · 0 comments

Comments

@ronghaoZHI
Copy link
Owner

ronghaoZHI commented May 14, 2020

HTML5 之 WebSocket

WebSocket作为HTML5 的新特性,实现了浏览器与服务器全双工通信(full-duplex),可以传输基于消息的文本和二进制数据。 相比于 http协议的半双工通信,WebSocket 具有很大的优势。
WebSocket 是浏览器中最靠近套接字的API,除最初建立连接时需要借助于现有的HTTP协议,其他时候直接基于TCP完成通信。
如果项目对通信的实时性要求较高,或者有不断 polling 轮询相关的需求, 那么就可以尝试着使用WebSocket。

WebSocket和长轮询之间的带宽消耗差异:

image

WebSocket 协议帧

WebSocket 使用了自定义的二进制分帧格式,把每个应用消息切分成一或多个帧(!!!注意 ws会自动切分多帧,收到数据有乱码现象时应考虑是否有分帧情况),发送到目的地之后再组装起来,等到接收到完整的消息后再通知接收端。
在打开握手完成后,终端发送一个关闭帧之前的任何时间里,数据帧可能由客户端或服务器的任何一方发送。
image

FIN: 1 bit 。表示此帧是否是消息的最后帧,第一帧也可能是最后帧。
RSV1,RSV2,RSV3: 各1 bit 。必须是0,除非协商了扩展定义了非0的意义。
opcode: 4 bit。表示被传输帧的类型:x0 表示一个后续帧;x1 表示一个文本帧;x2 表示一个二进制帧;x3-7 为以后的非控制帧保留;x8 表示一个连接关闭;x9 表示一个ping;xA 表示一个pong;xB-F 为以后的控制帧保留。
Mask: 1 bit。表示净荷是否有掩码(只适用于客户端发送给服务器的消息)。
Payload length: 7 bit, 7 + 16 bit, 7 + 64 bit。 净荷长度由可变长度字段表示: 如果是 0~125,就是净荷长度;如果是 126,则接下来 2 字节表示的 16 位无符号整数才是这一帧的长度; 如果是 127,则接下来 8 字节表示的 64 位无符号整数才是这一帧的长度。
Masking-key: 0或4 Byte。 用于给净荷加掩护,客户端到服务器标记。
Extension data: x Byte。默认为0 Byte,除非协商了扩展。
Application data: y Byte。 在”Extension data”之后,占据了帧的剩余部分。
Payload data: (x + y) Byte。”extension data” 后接 “application data”。

WS / WSS

WebSocket 资源URI采用了自定义模式:ws 表示纯文本通信( 如:ws://http://example.com/socket),wss 表示使用加密信道通信(TCP+TLS)

ws协议:普通请求,占用与http相同的80端口;
wss协议:基于SSL的安全传输,占用与tls相同的443端口。

对应各自的URI如下:

 ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
 wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]

WebSocket 的使用

浏览器提供的WebSocket API很简洁,调用示例如下:

 var ws = new WebSocket('ws://example.com/socket'); // 创建安全WebSocket 连接(wss)

 ws.onerror = function (error) { ... } // 错误处理
 ws.onclose = function () { ... } // 关闭时调用

 ws.onopen = function () { // 连接建立时调用
   ws.send("Connection established. Hello server!"); // 向服务端发送消息
 }

 ws.onmessage = function(msg) { // 接收服务端发送的消息
   if(msg.data instanceof Blob) { // 处理二进制信息
     processBlob(msg.data);
   } else {
     processText(msg.data); // 处理文本信息
   }
 }

WS 的属性及方法

属性:

readyState:
以下其中之一
0 (WebSocket.CONNECTING) 正在链接中
1 (WebSocket.OPEN) 已经链接并且可以通讯
2 (WebSocket.CLOSING) 连接正在关闭
3 (WebSocket.CLOSED) 连接已关闭或者没有链接成功

binaryType:
WebSocket.binaryType 返回websocket连接所传输二进制数据的类型。
返回值: "blob" (如果传输的是 Blob 类型的数据)、"arraybuffer" (如果传输的是 ArrayBuffer 类型的数据)

bufferedAmount:
WebSocket.bufferedAmount是一个只读属性,用于返回已经被send()方法放入队列中但还没有被发送到网络中的数据的字节数。一旦队列中的所有数据被发送至网络,则该属性值将被重置为0。但是,若在发送过程中连接被关闭,则属性值不会重置为0。如果你不断地调用send(),则该属性值会持续增长。

extensions:
WebSocket.extensions是只读属性,返回服务器已选择的扩展值。目前,链接可以协定的扩展值只有空字符串或者一个扩展列表。

onclose:
WebSocket.onclose 属性返回一个事件监听器,这个事件监听器将在 WebSocket 连接的readyState 变为 CLOSED时被调用。

onerror:
在 WebSocket.onerror 属性中,你可以定义一个发生错误时执行的回调函数,此事件的事件名为"error"
onmessage:
WebSocket.onmessage 属性是一个当收到来自服务器的消息时被调用的 EventHandler。

onopen:
WebSocket.onopen 属性定义一个事件处理程序,当WebSocket 的连接状态readyState 变为“OPEN”时调用;这意味着当前连接已经准备好发送和接受数据。

protocol:
WebSocket.protocol 是个只读属性,用于返回服务器端选中的子协议的名字;这是一个在创建WebSocket 对象时,在参数protocols中指定的字符串。

url:
WebSocket.url是一个只读属性,返回值为当构造函数创建WebSocket实例对象时URL的绝对路径。

方法:

WS 提供了可以 主动关闭 和 发送消息 两个方法
close()
WebSocket.close() 方法关闭 WebSocket 连接或连接尝试(如果有的话)。 如果连接已经关闭,则此方法不执行任何操作。

send()
WebSocket.send() 方法将需要通过 WebSocket 链接传输至服务器的数据排入队列,并根据所需要传输的data bytes的大小来增加 bufferedAmount的值 。若数据无法传输(例如数据需要缓存而缓冲区已满)时,套接字会自行关闭。

@ronghaoZHI ronghaoZHI changed the title websokect websocket Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant