使用原生的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 =false
clearInterval(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 = this
this.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 =false
clearInterval(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 = this
this.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>