websocket搭建及demo

一. 简单node搭建websocket服务端

下载插件

npm   i  nodejs-websocket  --save 

创建server.js文件

const ws = require("nodejs-websocket");
var _server = ws.createServer(conn => {
	// 接收客户端返回的数据
	conn.on("text", function(str) {     //监听客户端传过来的信息
		console.log(str,"接收客户端传过来的值");
	    //conn.sendText方法用于返回给客户端内容
        conn.sendText(JSON.stringify(
					{
						message:value.path + str
					}
				));
	});

    //客户端关闭连接
	conn.on("close", function() {
		
	});

	conn.on("error", function(err) {
		//error
		console.log(err, "连接报错");
	});
});
// 定义端口为8000【端口自己随意定义】已经被占用的端口, 会连接不上,需要自行更换端口
const port = 8000;
_server.listen(port, function() {
	console.log("连接成功")
	console.log('listening on websocketServer');
})

运行server.js文件, 每当server.js文件被更改后, 都需要重新运行

node ./server.js

二. websocket封装

心跳机制: 用于长时间无信息往来情况下, 保持活性

  • 1.连接服务器后开始发送心跳, 在服务端长时间无主动返回信息的情况下, 每隔10s发送一次, 间隔3s无返回则主动断线重连(判断依据是, 每当有信息返回则清空心跳定时器和延时器, 再重开心跳)
  • 2.在服务器一直不间断发送信息的情况下, 每次接收到信息, 则重新计算心跳间隔, 类似防抖效果
  • 3.封装主动清空心跳, 用于外部断开链接后使用

断线重连:

  • 1.主动断线: 组件销毁时, 手动断线, 无需重连
  • 2.被动断线: 心跳检测断线,本地网络问题, 服务端连接问题
  • 3.给节流,每2s内只能执行一次

关于close与error事件的发触发

  • 连接后服务端掉线, 只触发了close, 但是没有触发error
  • new websocket连接不上, 会触发close以及error事件
  • 网络慢造成的断线, 直接调用websocket.send会报错,此时调用websocket.close()是不会触发close事件的

完整封装websocket.js

export class WebSocketDerive {
  constructor(url, heartbeatTime = 10000, callBack) {
    this.url = url; //地址
    this.websocket = null; // 实例
    this.heartbeatTime = heartbeatTime; //心跳间隔时间,默认10s
    this.heartbeatInterval = null; //心跳定时器
    this.heartbeatTimeOut = null; //心跳返回判断
    this.reconnect = true; //是否断线重连, 默认为true, 自动重连
    this.callBack = callBack;//callBack是外部方法, 用于返回信息后调用传递信息出去
    this.connect(); //初始化连接
  }

  // 连接
  connect() {
    let _this = this;
    this.websocket = new WebSocket(this.url);

    this.websocket.onopen = function () {
      _this.startHeartbeat(); //开启心跳
    };

    // 返回信息处理
    this.websocket.onmessage = function (e) {
      let res = e.data ? JSON.parse(e.data) : null; //获取返回信息
      if (res) {
        _this.startHeartbeat(); //开启新心跳, 即重置心跳
        // 信息处理,传到外面
        _this.callBack && _this.callBack(res);
      }
    };
    this.websocket.onerror = function () {
      _this.reconnection();
      console.log("连接错误");
    };
    this.websocket.onclose = function () {
      _this.reconnection();
    };
  }

  // 心跳
  startHeartbeat() {
    this.stopHeartbeat(); //重置定时器与延时器
    this.heartbeatInterval = setInterval(() => {
      if (this.websocket.readyState == 1) {   //为open状态下才发送, 否则调用send会报错
        //发送心跳信息
        this.websocket.send(
          JSON.stringify({
            content: "ping",
          })
        );
      }

      //3s内没被重置则断线重连
      this.heartbeatTimeOut = setTimeout(() => {// 作用: 1.心跳send发送后无返回重连, 2.客户端网络错误时重连
        this.reconnection()
      }, 3000);
    }, this.heartbeatTime);
  }
  // 关闭心跳
  stopHeartbeat() {
    clearInterval(this.heartbeatInterval);
    clearTimeout(this.heartbeatTimeOut);
  }
  //发送消息
  send(message) {
    message = typeof message === String ? message : JSON.stringify(message);
    this.websocket.send(message);
  }
  //关闭连接,手动断线
  close() {
    this.reconnect = false;
    this.stopHeartbeat();
    this.websocket.close();
  }

  flag = false; //节流阀
  // 断线重连
  reconnection() {
    if (!this.reconnect) return false;

    if (!this.flag) {
      this.flag = true;
      this.stopHeartbeat();
      setTimeout(() => {
        this.connect();
        this.flag = false;
      }, 2000);
    }
  }
}

三. 使用

注意事项: 组件销毁时, 记得调用close方法, 否则心跳定时器没关会内存泄露

<template> 
  <div></div>
</template>
<script>
import  {WebSocketDerive}  from   "../../websocket.js"
export default {
    name: "HelloWorld",
    props: "",
    data() {
        return {
          websocket:null,//websocket实例
        };
    },
    methods: {
      callBack(message){
        console.log(message,"接收信息")
      }
    },
    mounted() {
      this.websocket = new WebSocketDerive('ws://localhost:8000',10000,callBack)
    },
    destroyed(){
      this.websocket.close()
    }
};
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值