使用原生的websocket实现websocket通信客户端是最简单原始的实现方式。主要是针对连接、数据发送、数据接收、断开连接、以及异常处理即可。
构建:
可以添加一个数组格式的自定义请求头信息,这个值会被放到Sec-WebSocket-Protocol请求头中。
this.ws = new WebSocket('ws://' + this.websocketPath, ['123456789']);this.ws.onmessage = this.websocketOnMessage;this.ws.onopen = this.websocketOpen;this.ws.onerror = this.websocketError;this.ws.onclose = this.websocketOnclose;
连接成功处理:
websocketOpen() {console.log('websocket onopen', this.ws.readyState);this.connected = true; },
连接失败处理:
websocketError(event) {console.log('websocket onerror', this.ws.readyState);this.connected =false}
数据发送:
sendMessage() {if (this.ws.readyState === WebSocket.OPEN) {let param = {message: this.message}this.ws.send(JSON.stringify(param));}},
数据接收:
websocketOnMessage(event) {console.log(`收到消息:${event.data}`);let nowMessage = '第' + this.number + '次收到订阅的消息:' + event.data + '\r\n';this.receiveMessage += nowMessage;this.number++this.resetHeartbeat();}
关闭连接:
websocketOnclose(event){// WebSocket关闭时的处理console.log('WebSocket disconnected');this.connected = false;},
可能还需要心跳保活机制,心跳保活需要和服务端指定规则,利用数据发送指定字符串来表示心跳。
websocketOpen() {console.log('websocket onopen', this.ws.readyState);this.connected = true;// 开始心跳检测this.startHeartbeat();},websocketError(event) {console.log('websocket onerror', this.ws.readyState);this.connected =falseclearInterval(this.heartbeatIntervalId);clearTimeout(this.timeoutId);},websocketOnclose(event){// WebSocket关闭时的处理console.log('WebSocket disconnected');// 清除心跳检测定时器clearInterval(this.heartbeatIntervalId);clearTimeout(this.timeoutId);this.connected = false;},websocketOnMessage(event) {console.log(`收到消息:${event.data}`);let nowMessage = '第' + this.number + '次收到订阅的消息:' + event.data + '\r\n';this.receiveMessage += nowMessage;this.number++this.resetHeartbeat();},
startHeartbeat() {let _that = this//开始心跳检测this.heartbeatIntervalId = setInterval( function () {//根据实际情况发送正确的心跳消息_that.ws.send('HEARTBEAT');}, 8 * 1000)this.timeoutId = setTimeout(() => {console.error('Heartbeat timeout, reconnecting...');console.log(this.ws)this.ws.close();}, 15 * 1000)},
resetHeartbeat() {clearTimeout(this.timeoutId);let _that = thisthis.timeoutId = window.setTimeout(function() {console.error('Heartbeat timeout, reconnecting...');_that.ws.close();}, 15 * 1000);},
完整代码如下:
<template><div class="f_c float_l"><div class="m_10"><el-input class='input_common' v-model="websocketPath" placeholder="请输入后端websocket地址" ></el-input><el-button v-if="!connected" @click=" initWebSocket" >连接</el-button><el-button v-else @click="disConnectWebsocket" >断开</el-button></div><div class="f_c" v-if="connected"><el-button @click="sendMessage">发送</el-button><el-input class='input_common mt_10' v-model="message" type="textarea" :rows="2" placeholder="请输入需要发送的消息"></el-input></div><el-divider /><div class="m_10 f_c" v-if="connected"><span class="float_l">收到消息</span><span style="border: aqua; width: 500px; height: 100px">{{receiveMessage}}</span></div></div>
</template><script>
export default {name: "index",data(){return {websocketPath:'localhost:7000/websocket-demo/websocket/log/getLog',userId:'',receiveMessage:'',message:'',connected: false,ws:null,number:0,heartbeatIntervalId: null, //客户端心跳定时发送timeoutId: null //定时检测服务端发送过来的心跳}},methods: {initWebSocket() {this.ws = new WebSocket('ws://' + this.websocketPath, ['123456789']);this.ws.onmessage = this.websocketOnMessage;this.ws.onopen = this.websocketOpen;this.ws.onerror = this.websocketError;this.ws.onclose = this.websocketOnclose;},websocketOpen() {console.log('websocket onopen', this.ws.readyState);this.connected = true;// 开始心跳检测this.startHeartbeat();},websocketError(event) {console.log('websocket onerror', this.ws.readyState);this.connected =falseclearInterval(this.heartbeatIntervalId);clearTimeout(this.timeoutId);},websocketOnclose(event){// WebSocket关闭时的处理console.log('WebSocket disconnected');// 清除心跳检测定时器clearInterval(this.heartbeatIntervalId);clearTimeout(this.timeoutId);this.connected = false;},websocketOnMessage(event) {console.log(`收到消息:${event.data}`);let nowMessage = '第' + this.number + '次收到订阅的消息:' + event.data + '\r\n';this.receiveMessage += nowMessage;this.number++this.resetHeartbeat();},sendMessage() {if (this.ws.readyState === WebSocket.OPEN) {let param = {message: this.message}this.ws.send(JSON.stringify(param));}},startHeartbeat() {let _that = this//开始心跳检测this.heartbeatIntervalId = setInterval( function () {//根据实际情况发送正确的心跳消息_that.ws.send('HEARTBEAT');}, 8 * 1000)this.timeoutId = setTimeout(() => {console.error('Heartbeat timeout, reconnecting...');console.log(this.ws)this.ws.close();}, 15 * 1000)},resetHeartbeat() {clearTimeout(this.timeoutId);let _that = thisthis.timeoutId = window.setTimeout(function() {console.error('Heartbeat timeout, reconnecting...');_that.ws.close();}, 15 * 1000);},disConnectWebsocket(){this.ws.close();clearInterval(this.heartbeatIntervalId);clearTimeout(this.timeoutId);}}
}
</script><style scoped></style>