WebSocket是一种在Web应用程序中实现实时双向通信的协议,一种在单个TCP连接上进行全双工通信的协议。它使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
WebSocket 与 HTTP/2 一样,其实都是为了解决 HTTP/1.1 的一些缺陷而诞生的,而 WebSocket 针对的就是 请求-应答 这种"半双工"的模式的通信缺陷。
请求-应答 是"半双工"的通信模式,数据的传输必须经过一次请求应答,这个完整的通信过程,通信的同一时刻数据只能在一个方向上传递。它最大的问题在于,HTTP 是一种被动的通信模式,服务端必须等待客户端请求才可以返回数据,无法主动向客户端发送数据。
那在 WebSocket 出现之前,一些对实时性有要求的服务,通常是基于轮询(Polling)这种简单的模式来实现。轮询就是由客户端定时发起请求,如果服务端有需要传递的数据,可以借助这个请求去响应数据。轮询的缺点也很明显,即是有大量空闲的时间,是在反复发送无效的请求,这显然是一种资源的损耗。
就可以简单当成 HTTP1.1是单向通信的,websocket是双向通信的。
想要在浏览器中实现双向通信,所以才有websocket。
而HTTP/2是支持双向通信的,其是在websocket后才出现的。
其如何使用c++去编写一个websocket服务器端程序,可以详细看这篇文章21.添加websocket模块
WebSocket的流程可以分为三个阶段:握手、数据传输和断开连接。
客户端发起WebSocket连接时,通过向服务器发送一个特殊的HTTP请求头来建立连接。服务器检查请求头中的特定字段,确认支持WebSocket协议后,发送特殊的HTTP响应头进行握手确认。握手成功后,双方建立了WebSocket连接,可以进行后续的数据传输。
客户端发送的握手请求
请求行中的请求方法必须是GET, HTTP版本至少是1.1
请求必须含有Connection, 其值必须含有"Upgrade"记号
请求必须含有Upgrade, 其值必须含有"websocket"关键字
请求必须含有Sec-Websocket-Version, 其值必须是13
请求必须含有Sec-Websocket-Key, 用于提供基本的防护, 比如无意的连接
服务端收到客户端握手连接的回复
响应行: HTTP/1.1 101 Switching Protocols
响应必须含有Upgrade, 其值为"weboscket"
响应必须含有Connection, 其值为"Upgrade"
响应必须含有Sec-Websocket-Accept, 根据请求头部的Sec-Websocket-key计算出来。
这个计算是有通过SHA1
计算出摘要, 并转成base64
字符串的。这个过程可以不用了解,我们是直接调用函数去获取结果的。
一旦建立了WebSocket连接,客户端和服务器可以通过该连接进行双向的实时数据传输。双方可以发送和接收消息,消息以帧的形式进行传输。WebSocket协议定义了不同类型的帧,如文本帧和二进制帧,用于传输不同类型的数据。
当连接不再需要时,客户端或服务器可以发起关闭连接的请求。双方会交换特殊的关闭帧,以协商关闭连接,并确保双方都接收到了关闭请求。
注意的点:
1.Fin为0,表示一个完整的消息被分片成多个数据帧进行传输的,需要一直等待接到Fin为1的数据帧之后,才算收到一个完整的消息。
2.只有客户端给服务器端发送数据时才会有masking key,服务器端给客户端发送数据不需要masking key。
3.若payload length占用了多个字节的话,payload length需要进行转序操作(网络序<->主机序)。