概述
Websocket是HTML5开始提供的,一种在单个TCP连接上,进行全双工通讯的协议。
详细讲解,如下链接:
关键词
TCP连接
传输控制协议(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。
建立连接
建立连接前,服务器端首先被动打开其熟知的端口,对端口进行侦听。当客户端要和服务器端建立连接时,发起一个主动打开端口的请求;然后进入三次握手的过程。
释放连接
数据传输结束后,通信双方都可以释放连接。
全双工通讯
Websocket是一种全双工协议。
何谓全双工,即客户端和服务器,通信时。在同一时刻,既可以发送数据,又可以接收数据。
对比HTTP
与之相反的HTTP是半双工。
在HTTP通信的过程中,一次只能执行一种操作,发送和接受不能同时进行。
使用Websocket有一个前提,在发送数据之前必须要创建连接,只有连接存在才可以传递数据。
信号不好会断网,网断了,Websocket连接也断了。
Websocket还有一个问题,发出去的消息并不一定会响应。
一言蔽之,使用http的项目更加健壮,使用websocket的项目更加脆弱。
通信过程
参考书籍:Spring实战(第4版)[美] 克雷格·沃斯
摘录如下,讲述了Websocket通信过程:
在WebSocket通信中,基于浏览器的JavaScript应用可能会发送消息到一个目的地,这个目的地由服务器端的组件来进行处理。
其实,反过来是一样的,服务器端的组件也可以发布消息,由JavaScript客户端的目的地来接收。
对于支持WebSocket的浏览器来说,这个类型是原生的。
通过创建WebSocket实例,实际上打开了到给定URL的WebSocket。在本例中,URL使用了“ws://”前缀,表明这是一个基本的WebSocket连接。如果是安全WebSocket的话,协议的前缀将会是“wss://”。
WebSocket创建完毕之后,接下来的代码建立了WebSocket的事件处理功能。在onopen事件中,设置了一个函数,在该WebSocket上发送消息。然后,这个无休止的游戏就开始了。
因为服务器端作为响应会将消息发送回来,当客户端收到来自服务器的消息后,onmessage事件会发送另外一个消息给服务器。
这个过程会一直持续下去,直到连接关闭。
如果调用sock.close()的话,将会结束这个疯狂的游戏。在服务端也可以关闭连接,或者浏览器转向其他的页面,都会关闭连接。
如果发生以上任意的场景,只要连接关闭,都会触发onclose事件。在这里,出现这种情况将会在控制台日志上记录一条信息。
应用
以具体项目中的应用为例
通过websocket请求,做消息提示的功能。
前端代码如下:
新建socket.js文件
function getSocket(url, params, callback) {
let socket;
if (typeof (WebSocket) === 'undefined') {
console.log('您的浏览器不支持WebSocket');
} else {
console.log('您的浏览器支持WebSocket');
// 初始化 WebSocket 对象,指定要连接的服务器地址与端口建立连接
socket = new WebSocket(url);
// 打开事件
socket.onopen = function() {
console.log('Socket 已打开');
socket.send(params);
};
// 获得消息事件
socket.onmessage = function(msg) {
// 发现消息进入, 开始处理前端触发逻辑
callback(msg, socket);
};
// 关闭事件
socket.onclose = function() {
console.log('Socket 已关闭');
};
// 发生了错误事件
socket.onerror = function() {
console.log('Socket 发生了错误,请刷新页面');
// 此时可以尝试刷新页面
};
}
}
export {
getSocket
};
复制代码
引入
//引入
import { getSocket } from "@/api/socket.js";
复制代码
收发消息
//方法
//接收消息
getSocketData() {
let params = {
sid: `index_${this.userInfo.id}`,
};
let sid = `index_${this.userInfo.id}`;
let url = this.baseUrl.replace("http://", "ws://");
getSocket(`${url}/websocket/${sid}`, JSON.stringify(params), (msg, ws) => {
// 保存数据对象, 以便发送消息
this.wsData = ws;
try {
let data = JSON.parse(msg.data);
let msgType = data.msgType;
} catch (error) {}
});
},
//发送消息
sendSocketData() {
let params = {};
this.wsData.send(JSON.stringify(params));
},
复制代码
关闭连接
//在生命周期beforeDestroy中关闭请求
beforeDestroy() {
this.wsData.close();
},
复制代码