WebSocket是什么
websocket是用来实现客户端和服务器之间数据通信的一种手段;即浏览器和服务器只需要建议一次连接,两者之间就可以实现双向数据传输
问题:已经有了HTTP协议,为什么还需要WebSocket?
HTTP协议的缺陷: 通信只能是客户端发起, 不具备服务器推送功能,也就是说服务器不能主动向客户端推送消息.
这种单向通信方式,需要使用[轮询]查询方式,每隔一段时间就发出一次询问,了解服务器有没有新的消息.这种方式效率很低,浪费资源。
WebSocket使用
- 建立连接
- 使用WebSocket,通过构造函数实例化
// 构造一个 webSocket 对象
const socket = new WebSocket('ws://localhost:8080');
// const socket = new WebSocket('wss://localhost:8080');
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
-
实例化对象包含的属性
image.png
每个属性的含义:
- binaryType:使用二进制的数据类型连接;
- bufferedAmount(只读):未发送至服务器的字节数;
- extensions(只读):服务器选择的扩展;
- onclose:用于指定连接关闭后的回调函数;
- onerror:用于指定连接失败后的回调函数;
- onmessage:用于指定当从服务器接受到信息时的回调函数;
- onopen:用于指定连接成功后的回调函数;
- protocol(只读):用于返回服务器端选中的子协议的名字;
- readyState(只读):返回当前 WebSocket 的连接状态,共有 4 种状态:
CONNECTING — 正在连接中,对应的值为 0;
OPEN — 已经连接并且可以通讯,对应的值为 1;
CLOSING — 连接正在关闭,对应的值为 2;
CLOSED — 连接已关闭或者没有连接成功,对应的值为 3; - url(只读):返回值为当构造函数创建 WebSocket 实例对象时 URL 的绝对路径;
WebSocket方法:
send(data):通过 WebSocket 连接传输至服务器的数据队列,并根据所需要传输的数据的大小来增加 bufferedAmount 的值;
close():关闭 WebSocket 连接,如果连接已经关闭,则此方法不执行任何操作;
WebSocket事件: close:当一个 WebSocket 连接被关闭时触发,也可以通过 onclose 属性来设置;
error:当一个 WebSocket 连接因错误而关闭时触发,也可以通过 onerror 属性来设置;
message:当通过 WebSocket 收到数据时触发,也可以通过 onmessage 属性来设置;
open:当一个 WebSocket 连接成功时触发,也可以通过 onopen 属性来设置;
- 项目中使用WebSocket
<script>
export default {
data() {
return {
socket: null,
aliveTime: new Date().getTime(),
checkTimer: null
}
},
computed: {
token() {
return this.$store.getters.token
}
},
beforeDestroy() {
clearInterval(this.checkTimer)
this.socket && this.socket.close()
},
mounted() {
if (this.socket && this.socket.readyState === 1) {
clearInterval(this.checkTimer)
this.socket.close()
}
if (this.socket && this.socket.readyState === 3) {
this.initWebSocket()
}
this.getData()
},
methods: {
getData() {
// ......
this.initWebSocket()
},
initWebSocket() {
if (typeof WebSocket === 'undefined') {
this.$message({ message: '您的浏览器不支持WebSocket' })
return false
}
this.checkTimer && clearInterval(this.checkTimer)
this.socket && this.socket.close()
this.aliveTime = new Date().getTime()
const token = this.token.split('Bearer ')[1]
const wsurl = `wss://${process.env.VUE_APP_DOMAIN}/ws?token=${token}`
this.socket = new WebSocket(wsurl)
this.socket.onmessage = this.websocketonmessage
this.socket.onerror = this.websocketonerror
this.checkTimer = setInterval(this.checkWebsocketAlive, 5 * 1000)
},
websocketonmessage(e) {
const response = JSON.parse(e.data)
if (response.message === 'success') {
const data = response.data
// 处理 data
}
// 这里的场景是服务端主动推数据,接收到消息说明连接正常
if (response.message === 'connection alive') {
this.aliveTime = new Date().getTime()
}
},
websocketonerror() {
clearInterval(this.checkTimer)
this.socket.close()
},
checkWebsocketAlive() {
const now = new Date().getTime()
if (now - this.aliveTime > 60 * 1000) {
this.aliveTime = now
this.initWebSocket()
}
},
}
}
</script>
- 应用场景
- 即时聊天通信
- 多玩家游戏
- 在线协同编辑/编辑
- 实时数据流的拉取与推送
- 体育/游戏实况
- 实时地图位置
解释:
即时Web应用程序:即时Web应用程序使用一个Web套接字在客户端显示数据,这些数据由后端服务器连续发送。在WebSocket中,数据被连续推送/传输到已经打开的同一连接中,这就是为什么WebSocket更快并提高了应用程序性能的原因。 例如在交易网站或比特币交易中,这是最不稳定的事情,它用于显示价格波动,数据被后端服务器使用Web套接字通道连续推送到客户端。
游戏应用程序:在游戏应用程序中,你可能会注意到,服务器会持续接收数据,而不会刷新用户界面。屏幕上的用户界面会自动刷新,而且不需要建立新的连接,因此在WebSocket游戏应用程序中非常有帮助。
聊天应用程序:聊天应用程序仅使用WebSocket建立一次连接,便能在订阅户之间交换,发布和广播消息。它重复使用相同的WebSocket连接,用于发送和接收消息以及一对一的消息传输。
参考
作者:你听得到11
链接:https://juejin.cn/post/7283311024978427961