WebSocket介绍
- WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
- WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
- 在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
- 现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
image.png
WebSocket特点
特点:
- 建立在 TCP 协议之上,服务器端的实现比较容易。
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
- 数据格式比较轻量,性能开销小,通信高效。
- 可以发送文本,也可以发送二进制数据。
- 没有同源限制,客户端可以与任意服务器通信。
- 协议标识符是
ws
(如果加密,则为wss
),服务器网址就是 URL。
示例:
ws://example.com:80/some/path
image.png
WebSocket 简单示例
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
WebSocket API
WebSocket 构造一个函数
执行下面语句之后,客户端就会与服务器进行连接。
var ws = new WebSocket('ws://localhost:8080');
WebSocket 事件
事件 |
事件处理程序 |
描述 |
---|---|---|
open | ws.onopen | 连接建立时触发 |
message | ws.onmessage | 客户端接收服务端数据时触发 |
error | ws.onerror | 通信发生错误时触发 |
close | ws.onclose | 连接关闭时触发 |
总合示例
//心跳检测
var heartCheck = {
timeout: 5000, //每隔90秒发送心跳
severTimeout: 10000, //3分钟服务端超时时间
timeoutObj: null,
serverTimeoutObj: null,
start: function() {
var _this = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function() {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("test"); // 心跳包
//计算答复的超时时间
_this.serverTimeoutObj = setTimeout(function() {
ws.close();
}, _this.severTimeout);
}, this.timeout)
}
}
let Url = "ws://312f020x02.zicp.vip/openApi/webSocket/100"
var ws = new WebSocket(Url);
let tips = []
let data = {};
let msgsOrder = [];
let time = '';
function init(){
ws.onopen = function(evt) {
ws.send("Hello WebSockets!");
heartCheck.start();
};
ws.onmessage = function(evt) {
data = evt.data;
let datas = [];
if(data == 'test'){
heartCheck.start();
}
if (data == 'conn_success' || data == 'Hello WebSockets!'|| data == 'test') {
} else {
datas.push(JSON.parse(data))
}
tips = datas;
tips.map(res => {
console.log(res.data)
// ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
reconnect(Url)
};
ws.onerror = function() {
//连接报错
reconnect(Url)
// console.log('连接报错')
};
}
// 重连
function reconnect(url) {
setTimeout(function() { //没连接上会一直重连,设置延迟避免请求过多
createWebsocket(url);
}, 3000);
}
//建立websocket连接函数
function createWebsocket(url) {
try {
ws = new WebSocket(url);
init();
} catch (e) {
//进行重连;
console.log('websocket连接错误');
reconnect(url);
}
}
init();