vue实现原生的websocket客户端(一)

11 篇文章 0 订阅

        使用原生的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>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值