WebSocket协议可以为网站和应用提供真正的双向通信,具有控制开销、保持连接状态、更强实时性、更好的压缩效果等优点,是当下低延时应用最常采用的一种技术协议。
websocket作为用于双向通信的实用协议,在笔者最近做的全平台私信系统进行了应用。本次开发的私信系统与普遍理解的“发送-接受-发送”三个流程分开不一样,实现的是类似于QQ与微信的实时通信系统,需要做到收发消息实时化。
进行通信协议选定的时候,不能由服务器主动联系客户端,又因为每次通信都需要经过握手请求、响应步骤进行连接重建的http协议只能通过轮询进行伪双向通信,所以http协议首先被我们排除了,在HTML5下的协议websocket映入了我们的眼帘。
WebSocket能更好的节省服务器资源和带宽,并且能够更实时地进行通讯,它的优势:
• 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。
• 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
• 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
• 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
• 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。
• 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
一、 在线聊天速度慢,断开连接较快,不能更好的保持业务通讯
二、 网页通讯信息更安全,连接更稳定
三、 提供更高效的网页通讯
四、 网络抖动带来的连接时断时续问题
五、 访问打不开网页,需要刷新页面
六、 同时在线人数多,如何实时推送所有用户
七、 服务端支持WebSocket协议
八、 如何降低带宽,保证成本
总之,如果你的应用需要提供多个用户相互交流,或者展示服务器端经常变动的数据,就十分需要使用WebSocket技术。
首先要明确的一点是,支持websocket协议的客户端和服务器能够使用websocket协议进行双向通信,也就是客户端可以随时向服务器发送请求,服务器也能够随时向客户端发送请求。
跟http使用轮询实现不一样的是websocket一次连接成功后则可以重复进行请求和响应,更好地节省了服务器的资源与带宽。
websocket与http协议类似的是同样建立于tcp传输协议之上,通过tcp传输层进行数据传输。而客户端与服务器端一般使用的通信协议仍是http,我们要使用websocket协议进行通信则首先要建立起websocket连接,这个连接的建立依赖于http。
一个websocket连接首先发送http请求到服务器,注意比起平常的http请求多了4个字段,sec-WebSocket-* 为建立websocket协议的参数,upgrade字段才是重点,告诉服务器我这次的请求不是单纯的http请求,而是要求服务器升级连接并建立起websocket长连接。
服务器响应也根据特殊的请求头进行了特殊响应,首先101返回码表明本次连接的通信协议经过了转换并成功握手成功建立起了通信。connection字段和upgrade字段则表明本次通信协议进行了升级转换,转换的是websocket协议。
websocket的协议标识符为ws,从下图Request URL看到本次websocket连接的协议标识符为wws,这表示websocket连接是经过加密处理的。
建立了websocket连接后,只要客户端和服务器端任意一端不主动断开连接前,通信行为都是在一个持久连接上发起,后续数据与请求都通过帧序列的形式进行传输。
从chrome控制台的Websocket调试面板中可以看到,在一个websocket连接中多次请求都可以由服务器进行实时响应,实行实时上下行通信的能力得以见证。
通过WebSocket构造函数可以创建websocket连接并返回提供管理该连接API的实例对象。
const ws = new WebSocket('wws://url');
事件&属性 | 定义 |
---|---|
onopen | 服务器端响应连接请求后,readyState状态置为OPEN时触发。标志着握手阶段已结束,可以进行收发消息。 |
onmessage | 服务器端有消息到达时触发,可以接受文本和二进制数据。 |
onclose | 连接关闭时,readyState状态置为CLOSED时触发。标志着服务器端与客户端不能再通信。 |
onerror | 错误发生时触发,会导致连接关闭。 |
readyState | websocket连接状态。CONNECTING(连接中) OPEN(连接成功) CLOSING(关闭中) CLOSED(已关闭) |
protocol | websocket连接协议。ws & wws |
bufferedAmount | 调用send方法后在发送队列缓存中的数据量,所有消息已发出则清零。 |
binaryType | 当收到二进制数据时,用于表示该二进制数据的类型(blob & arraybuffer) |
// 监听到open事件后,向服务器发送success文本。ws.addEventListener('open', (e) => { ws.send('success!');})
(1) send 方法
// 文本数据const text = 'i am text';// 二进制数据const blob = new Blob('i am blob');ws.send(text);ws.send(blob);
(2) close 方法
close方法可以传入两个参数 code 和 reason ,用于向服务器端说明关闭连接原因。
ws.close(1000, 'mission finished');// 不传任何参数,默认code是1000,表示正常关闭ws.close();
在需要实现双向实时通信的场景下,不妨直接使用websocket协议吧。但是目前IE8和IE9是不支持websocket的,要实现该功能还是只能通过http 的long polling 方式去实现。
以上是websocket的基础理论,希望了解后有助于大家的实践!
扫码赞赏,鼓励支持
相关问题
Centos 7.x 下做端口映射/端口转发Windows server 2008/2012/2016/2019 服务器桌面不显示我的电脑(计算机)的解决方案No input file specified的解决方法网站如何添加工信部网站备案号和链接代码腾讯云对象存储内网与外网地址访问Windows远程桌面多个用户如何同时使用Chrome谷歌浏览器?