Java WebSocket编程(二):WebSocket实现主动推送交互

WebSocket协议

WebSocket协议通信机制

WebSocket协议是独立的、基于TCP的协议。其本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接,此后服务器端与客户器端通过此TCP连接进行实时通信。
这里写图片描述


WebSocket打开握手

每个socket连接都始于一个HTTP请求,该请求包含一个特殊的首标Upgrade。Upgrade首标表示客户端会将连接升级到不同的协议。在这种情况下,这个不同的协议就是WebSocket。

发送握手请求

客户端通过HTTP协议传输WebSocket支持的版本号、HTTP协议的版本号、原始地址和主机地址等字段给服务器端。客户端发送的HTTP请求代码如下:

GET /chat HTTP 1.1
Host: server.example.com
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

这个升级的请求头增加了以下字段:

  • Sec-WebSocket-Protocol:客户端可以接收的子协议的类型,即在WebSocket协议之上的应用层协议类型。
  • Connection:告知服务器端当前请求连接是升级的HTTP请求。
  • Origin:防止客户端使用脚本进行未授权的跨源攻击。服务器端根据这个字段判断是否接受客户端的Socket连接。可以返回一个HTTP错误状态码来拒绝连接。
  • Sec-WebSocket-Key:为了表示服务器端同意和客户端进行Socket连接,服务器端需要使用该字段进行校验,然后返回一个校验过的字符串给客户端,客户端验证通过后才能正式建立Socket连接。
  • Sec-WebSocket-Version:表示版本兼容性。

返回握手应答

WebSocket服务器端收到客户端发送的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等,就接收本次握手链接,并给出响应的数据回复。服务器端返回的响应代码如下:

HTTP/1.0 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: xxxxxxxxxxxxxxxxxxxxxxxx
Sec-WebSocket-Protocol: chat

响应代码中包含以下字段:

  • Sec-WebSocket-Accept:服务器端将加密处理后的握手Key通过这个字段返回给客户端,表示同意握手建立连接。
  • Sec-WebSocket-Protocol:服务器选择的一个应用层协议。

客户端收到服务器端回复的数据包后,如果数据包内容、格式都正确,就表示本次连接成功,升级为WebSocket协议,这也称作WebSocket初始握手(Opening Handshak)。


数据帧传输格式

WebSocket连接打开时,客户端和服务器端可以互相发送数据,数据使用一系列帧来传输。基本的数据帧由一个opcode、一个payload长度和发送的应用数据等组成。

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-------+-+-------------+-------------------------------+
 |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 | |1|2|3|       |K|             |                               |
 +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 |     Extended payload length continued, if payload len == 127  |
 + - - - - - - - - - - - - - - - +-------------------------------+
 |                               |Masking-key, if MASK set to 1  |
 +-------------------------------+-------------------------------+
 | Masking-key (continued)       |          Payload Data         |
 +-------------------------------- - - - - - - - - - - - - - - - +
 :                     Payload Data continued ...                :
 + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 |                     Payload Data continued ...                |
 +---------------------------------------------------------------+
  • FIN:1bit,表示是消息的最后一帧。
  • RSV1,RSV2,RSV3:每个1bit,必须是零,除非扩展定义为非零,如果接收到的是非零值但是扩展没有定义,则需要关闭连接。
  • Opcode:4bit,解释payload数据,规定有以下不同的状态,如果未知则接收方马上关闭连接。状态如下:0x0(附加数据帧)、0x1(文本数据帧)、0x2(二进制数据帧)、0x3-7(保留为之后非控制帧使用)、0xB-F(保留位后面的控制帧使用)、0x8(关闭连接帧)、0x9(ping)、0xA(pong)。
  • Mask:1bit,掩码,定义payload数据是否进行了掩码处理。
  • Masking-Key: 0到4子节,掩码解密密钥,用于解码Payload Data。客户端发出的数据帧需要进行亚麻处理,所以此位是1。
  • Payload length:7bit、7+16bit或7+64bit。payload Data的长度。
  • Payload data:任意长度数据。包含有扩展定义数据和应用数据。

WebSocket关闭握手

正常关闭握手的步骤:

  1. 当一端接收到一个关闭帧,且先前没有发送关闭帧,则这一端必须发送一个关闭帧作为响应。
  2. 当接收到这个响应帧时,接收这一端关闭连接,同时发送表明关闭连接的控制帧,不再发送数据。
  3. 另一端接收到表示应该关闭连接的控制帧后,丢弃后面接收的所有数据,关闭连接。

但是TCP关闭握手并不总是端到端可靠的,特别是出现拦截代理和其他的中间设施。当WebSocket关闭时,终止连接的端点可以发送一个数字代码,以及一个表示选择关闭套接字原因的字符串。代码1000~1015规定用于WebSocket连接层。


WebSocket协议通信实现的相关技术

WebSocket构造函数

WebSocket构造函数语法格式如下:

扫描二维码关注公众号,回复: 4419771 查看本文章
var ws = new WebSocket("ws://127.0.0.1/WebSocket/websocket")

URL地址的字符串需要以“ws”或“wss”(加密通信时使用)作为开头。


WebSocket事件

客户端的应用程序通过监听WebSocket对象上的事件,来及时处理数据和改变连接的状态。WebSocket对象可以触发4种事件,包括

  • open事件:WebSocket连接建立。
  • message事件:客户端接收到服务器端的数据。
  • error事件:通信过程中发生错误。
  • close事件:连接关闭。

WebSocket方法

  • send()方法:发送数据到服务器端。
  • close()方法:关闭WebSocket连接。可选参数:code(数字型的状态代码)、reason(文本字符串)。

猜你喜欢

转载自blog.csdn.net/MeowingCat/article/details/80209520
今日推荐