手机网站设计费用,wordpress 评论编辑器,WordPress建站 用插件,网页设计html5一、什么是Websocket
WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议#xff0c;它可以让客户端和服务器之间进行实时的双向通信。
WebSocket 使用一个长连接#xff0c;在客户端和服务器之间保持持久的连接#xff0c;从而可以实时地发送和接收数据。
在 Web…一、什么是Websocket
WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议它可以让客户端和服务器之间进行实时的双向通信。
WebSocket 使用一个长连接在客户端和服务器之间保持持久的连接从而可以实时地发送和接收数据。
在 WebSocket 中客户端和服务器之间可以互相发送消息客户端可以使用 JavaScript 中的 WebSocket API 发送消息到服务器也可以接收服务器发送的消息。
二、Websocket特点
简单来说websocket 具有 双向通信实时性强支持二进制控制开销 的特点。
1、协议标识符是ws如果加密则为wss服务器网址就是 URL。
2、实时通信服务器可以随时主动给客户端下发数据。
3、保持连接状态Websocket需要先创建连接所以是一种有状态的协议之后通信时就可以省略部分状态信息。
4、控制开销连接创建后服务器和客户端之间交换数据时用于协议控制的数据包头部相对较小。在不包含扩展的情况下对于服务器到客户端的内容此头部大小只有2至10字节和数据包长度有关对于客户端到服务器的内容头部还需要加上额外的4字节的掩码。
5、实现简单建立在 TCP 协议之上服务器端的实现比较容易并且没有同源限制客户端可以与任意服务器通信。
6、支持二进制传输Websocket定义了二进制帧可以发送文本也可以发送二进制数据。
7、与 HTTP 协议有着良好的兼容性。默认端口也是80和443并且握手阶段采用 HTTP 协议因此握手时不容易屏蔽能通过各种 HTTP 代理服务器。
8、支持扩展用户可以扩展协议、实现部分自定义的子协议如部分浏览器支持压缩等。
三、WebSocket与HTTP的区别
websocket和http都是基于TCP的应用层协议使用的也是 80 端口若运行在 TLS 之上时默认使用 443 端口。
其区别主要就在于连接的性质和通信方式。
WebSocket是一种双向通信的协议通过一次握手即可建立持久性的连接服务器和客户端可以随时发送和接收数据。
而HTTP协议是一种请求-响应模式的协议每次通信都需要发送一条请求并等待服务器的响应。
WebSocket的实时性更好延迟更低并且在服务器和客户端之间提供双向的即时通信能力适用于需要实时数据传输的场景。
四、常见应用场景
实时聊天WebSocket能够提供双向、实时的通信机制使得实时聊天应用能够快速、高效地发送和接收消息实现即时通信。实时协作用于实时协作工具如协同编辑文档、白板绘画、团队任务管理等团队成员可以实时地在同一页面上进行互动和实时更新。实时数据推送用于实时数据推送场景如股票行情、新闻快讯、实时天气信息等服务器可以实时将数据推送给客户端确保数据的及时性和准确性。多人在线游戏实时的双向通信机制适用于多人在线游戏应用使得游戏服务器能够实时地将游戏状态和玩家行为传输给客户端实现游戏的实时互动。在线客服WebSocket可以用于在线客服和客户支持系统实现实时的客户沟通和问题解决提供更好的用户体验减少等待时间。
五、websocket实例 为了建立一个 WebSocket 连接客户端浏览器首先要向服务器发起一个 HTTP 请求这个请求和通常的 HTTP 请求不同包含了一些附加头信息其中附加头信息Upgrade: WebSocket表明这是一个申请协议升级的 HTTP 请求服务器端解析这些附加的头信息然后产生应答信息返回给客户端客户端和服务器端的 WebSocket 连接就建立起来了双方就可以通过这个连接通道自由的传递信息并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
1Websocket事件
onopen: 客户端和服务器建立连接后触发被称为客户端和服务器之间的初始握手。如果接收到open, 说明已经连接成功可以进行通信了。onmessage 接收到消息时触发。服务器发送给客户端的消息可包括纯文本消息二进制数据Blob消息或者ArrayBuffer消息。onerror 响应意外故障时触发在错误之后总是会终止连接。onclose连接关闭时触发。一旦连接关闭后客户端和服务端将不会再进行消息的收发。也可主动调用close()方法关闭连接。
2Websocket方法
send() : 在连接成功后关闭前发送消息onopen后和onclose前才可发送消息close() : 关闭连接
3Websocket对象属性
readyState只读属性表示Websocket的连接状态。 CONNECTING — 正在连接中对应的值为 0OPEN — 已经连接并且可以通讯对应的值为 1CLOSING — 连接正在关闭对应的值为 2CLOSED — 连接已关闭或者没有连接成功对应的值为 3。 bufferedAmount只读属性。已被 send() 放入正在队列中等待传输但是还没有发出的 UTF-8 文本字节数。Protocol打开握手期间使用的协议。
4websocket请求报文
// websocket握手客户端发送的请求头
GET wss://www.example.cn/webSocket HTTP/1.1 // 使用的https协议, 对应的wss请求
Host: www.example.cn
Connection: Upgrade // 带upgrade头的http1.1消息必须含有connection头表示任何接受此消息的人都在转发此消息之前处理掉connection中指定的域即不转发upgrade域
Upgrade: websocket // 定义转换协议的header域如果服务器支持客户端希望使用已经建立好的httptcp连接
Sec-WebSocket-Version: 13 // 客户端支持的WebSocket协议的版本列表
Origin: http://example.cn // Origin为安全使用防止跨站攻击浏览器一般会使用这个来标识原始域类似于Referer。但与Referer 不同的是Origin 只包含了协议和主机名称
Sec-WebSocket-Key: afmbhhBRQuwCLmnWDRWHxw // 客户端随机生成的字符串服务器会使用此字段组装成另一个key值构造出一个SHA-1 的信息摘要放在握手返回信息里用于客户端到服务器websocket的初始握手避免夸协议攻击
Sec-WebSocket-Protocol: chat, superchat // 首标告诉客户端应用程序可使用的协议
Sec-WebSocket-Extensions: permessage-deflate // 首标permessage-deflate协商使用传输数据压缩client_max_window_bits擦采用LZ77压缩算法时滑动窗口相关SIZE大小// websocket握手服务器发出的响应头
HTTP/1.1 101 // 服务端响应101状态码、Upgrade和Sec-WebSocket-Accept首标才算连接成功否则不能连接成功。
Server: nginx/1.12.2
Date: Sat, 11 Aug 2018 13:21:27 GMT
Connection: upgrade // 指定一项或多项协议名按优先级排序以逗号分隔这里表示升级为 WebSocket 协议
Upgrade: websocket
Sec-WebSocket-Accept: sLMyWetYOwus23qJyUD/fa1hztc // 根据Sec-WebSocket-Key加上特殊字符串计算SHA-1摘要再进行 Base64编码协议生成可尽量避免普通HTTP请求被误认为WebSocket协议
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits155简单应用示例
templatedivinput typetext :valueinputVal /button clickhandleSendsend/button/div
/templatescript setup langts
import { ref } from vue;const inputVal ref();const handleSend () {socket.send(inputVal.value);
};// 创建WebSocket对象并指定服务器的地址
const socket new WebSocket(ws://82.157.123.54:9010/ajaxchattest);// 与服务器建立连接发送消息到服务器
socket.onopen () {console.log(connect: );
};
// 收到服务器发送的消息event处理服务器返回的数据
socket.onmessage (event) {console.log(receive: , event.data);
};
// 连接或通信过程中发生错误
socket.onerror (event) {console.log(errror: , event.error);
};
// 与服务器断开连接
socket.onclose (event) {console.log(close: , event.code);
};
/script六、websocket心跳机制
1、作用使 WebSocket 连接保持长连接避免断开连接的情况发生。同时心跳机制也可以检查WebSocket连接的状态及时处理异常情况。还可以减少WebSocket连接及服务器资源的消耗。
2、原理是利用心跳包及时发送和接收数据保证WebSocket长连接不被断开。
3、详细流程 客户端建立WebSocket连接。 客户端向服务器发送心跳数据包心跳包是指在一定时间间隔内WebSocket发送的空数据包服务器接收并返回一个表示接收到心跳数据包的响应。 当服务器没有及时接收到客户端发送的心跳数据包时服务器会发送一个关闭连接的请求。 服务器定时向客户端发送心跳数据包客户端接收并返回一个表示接收到心跳数据包的响应。 当客户端没有及时接收到服务器发送的心跳数据包时客户端会重新连接WebSocket
4、实现方式 使用setInterval定时发送心跳包。对服务器造成很大的压力因为即使WebSocket连接正常也要定时发送心跳包从而消耗服务器资源。 在前端监听到WebSocket的onclose()事件时重新创建WebSocket连接。减轻了服务器的负担但是在重连时可能会丢失一些数据。
5、WebSocket重连
重连意思就是在WebSocket断开之后重新建立连接这里指由于异常断开需要重新连接。
常用实现方法有下 1前端监听WebSocket的onclose()事件重新创建WebSocket连接。 2使用WebSocket插件或库例如Sockjs、Stompjs等。 3使用心跳机制检测WebSocket连接状态自动重连。 4使用断线重连插件或库例如ReconnectingWebSocket等。
6、通过WebSocket心跳机制实现重连
思路 在建立长连接的时候开启心跳 通过和服务端发送信息得到服务端给返回的信息然后重置心跳 清除时间再重新开启心跳。如果网络断开的话会执行方法重新连接
templatedivinput typetext :valueinputVal /button clickhandleSendsend/button/div
/templatescript setup langts
import { ref } from vue;const inputVal ref();let ws: any null; // websocket实例
let isConnect: Boolean false; // 连接标识 避免重复连接
let reciveCode: any null; // 断线重连后延迟5秒重新创建WebSocket连接reciveCode用来存储延迟请求的代码
let timeoutObj: any null; // 延时发送消息对象启动心跳时新建这个对象收到消息后重置这个对象// websocket重连
const reConnect () {// 如果已经连上就不在重连了if (isConnect) {return;}clearTimeout(reciveCode);// 延迟5秒重连 避免过多次过频繁请求重连reciveCode setTimeout(() {newWebSocket();}, 5000);
};// 创建并初始化websocket实例
const newWebSocket () {// 判断当前环境是否支持Websocketif (window.WebSocket) {if (!ws) {// 创建WebSocket对象并指定服务器的地址ws new WebSocket(ws://82.157.123.54:9010/ajaxchattest);}// 与服务器建立连接ws.onopen () {console.log(connect: );isConnect true;// 5分钟发一次心跳比server端设置的连接时间稍微小一点在接近断开的情况下以通信的方式去重置连接时间。timeoutObj setTimeout(() {if (isConnect) ws.send(inputVal.value);}, 300000);};// 收到服务器发送的消息ws.onmessage (event: any) {console.log(receive: , event, event.data);clearTimeout(timeoutObj);};// 连接或通信过程中发生错误ws.onerror (event: any) {console.log(errror: , event.error);isConnect false; //连接错误 需要重连reConnect();};// 与服务器断开连接ws.onclose (event: any) {console.log(close: , event.code);isConnect false;// 连接错误 需要重连reConnect();};} else {console.log(当前浏览器不支持websocket);}
};const handleSend () {newWebSocket();if (ws.readyState ws.OPEN) {// ws开启状态ws.send(inputVal.value);} else if (ws.readyState ws.CONNECTING) {// 正在开启状态则等待1s后重新调用setTimeout(function () {handleSend();}, 1000);} else {// 若未开启 则等待1s后重新调用setTimeout(function () {handleSend();}, 1000);}
};
/script