当前位置:   article > 正文

【自用笔记】webSocket 心跳机制、断线重连_websocket 心跳包一般设置多少

websocket 心跳包一般设置多少

在业务中需要使用webSocket定时给后台上传位置,防止以后忘记,在这里进行记录,直接在代码中写入笔记;

  1. <template>
  2. <div id='main' ref='main'>
  3. <van-button @click="OnLocation">开启</van-button>
  4. <van-button @click="OnClose">关闭socket</van-button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data() {
  10. return {
  11. lc: {}, // 经纬度
  12. ws: null, // webSocket实例
  13. webSocketState: false, // webSocket的连接状态
  14. heartBeat: { // 心跳连接的时间设置
  15. time: 5 * 1000, // 心跳时间间隔
  16. timeout: 3 * 1000, // timeout:心跳超时间隔(!要少于心跳间隔)
  17. reconnect: 10 * 1000 // 断线重连时间
  18. },
  19. reconnectTimer: null, // 断线重连时间器
  20. }
  21. },
  22. methods: {
  23. OnClose() {
  24. this.ws.close(); //关闭webSocket连接
  25. this.webSocketState = false; //关闭状态
  26. this.heartBeat.time = null; //停止心跳
  27. if (this.reconnectTimer) { //关闭重连
  28. clearInterval(this.reconnectTimer);
  29. }
  30. },
  31. //开启按钮
  32. OnLocation() {
  33. this.heartBeat.time = 5 * 1000; //因为关闭时会置空,所以在这重新初始化一下
  34. this.wlhy.getLocation(); //这里是我自己业务中取经纬度的,
  35. this.connectWebSocket(); //建立连接
  36. },
  37. //socket链接
  38. connectWebSocket() {
  39. let url = `wss://ws://baidu.com/msg/${this.userInfo.userId}`;
  40. //这里连接地址根据自己的业务设置,注意:如果连接本地进行调试的时候,要用'ws',如:“ws://192.168.2.15:8080/msg”
  41. this.ws = new WebSocket(url);
  42. this.init(); //初始化
  43. },
  44. init() {
  45. this.ws.addEventListener('open', () => {
  46. // eslint-disable-next-line spaced-comment
  47. this.webSocketState = true; //socket状态设置为连接,做为后面的断线重连的拦截器
  48. // eslint-disable-next-line no-unused-expressions
  49. console.log('开启');
  50. this.heartBeat && this.heartBeat.time ? this.startHeartBeat(this.heartBeat.time) : ''; // 是否启动心跳机制
  51. });
  52. this.ws.addEventListener('message', (e) => {
  53. this.webSocketState = true;
  54. console.log(JSON.parse(e.data),'信息')
  55. });
  56. this.ws.addEventListener('close', (e) => {
  57. this.webSocketState = false; // socket状态设置为断线
  58. console.log('断开了连接');
  59. });
  60. this.ws.addEventListener('error', (e) => {
  61. this.webSocketState = false; // socket状态设置为断线
  62. this.reconnectWebSocket(); // 重连
  63. console.log('连接发生了错误');
  64. });
  65. },
  66. // 心跳 time:心跳时间间隔
  67. startHeartBeat(time) {
  68. setTimeout(() => {
  69. //这里设置这是你要发送的内容
  70. let data = {};
  71. data.lon = this.lc.longitude; //已省略获取地址步骤
  72. data.lat = this.lc.latitude;
  73. this.ws.send(JSON.stringify(data)) //发送数据
  74. this.waitingServer();
  75. }, time);
  76. },
  77. // 延时等待服务端响应,通过webSocketState判断是否连线成功
  78. waitingServer() {
  79. this.webSocketState = false;
  80. setTimeout(() => {
  81. if (this.webSocketState) {
  82. this.startHeartBeat(this.heartBeat.time);
  83. return;
  84. }
  85. console.log('心跳无响应,已断线');
  86. try {
  87. this.ws.close();
  88. } catch (e) {
  89. console.log('连接已关闭,无需关闭');
  90. }
  91. this.reconnectWebSocket(); //非主动关闭导致,触发重连
  92. }, this.heartBeat.timeout);
  93. },
  94. // 重连操作
  95. reconnectWebSocket() {
  96. this.reconnectTimer = setTimeout(() => {
  97. this.reconnectWs();
  98. }, this.heartBeat.reconnect);
  99. },
  100. reconnectWs() {
  101. if(!this.heartBeat.time) return //如果主动关闭,则防止重连
  102. if (!this.ws) {
  103. // 第一次执行,初始化
  104. this.connectWebSocket();
  105. }
  106. if (this.ws && this.reconnectTimer) {
  107. // 防止多个websocket同时执行
  108. clearTimeout(this.reconnectTimer);
  109. this.ws.reconnectTimer = null;
  110. this.connectWebSocket();
  111. }
  112. },
  113. },
  114. }
  115. </script>

注意:我在开发过程中发现,当我主动关闭连接后,在重连时间内会自动重新开启连接,这是因为websocket连接关闭会又走一次重连机制,所以 如果你是使用的定时器,可以直接清除定时器,或者定义一个变量控制是组件销毁关闭的websocket还是心跳监测重连时关闭的websocket,如果是像我一样,可以判断this.heartBeat.time,关闭后置空,判断return就可以了;

下面是直接用定时器做的心跳(在这里没有主动关闭的功能)

  1. <script>
  2. export default {
  3. name: "clockIn",
  4. data(){
  5. return {
  6. lc: {}, //经纬度(获取过程省略)
  7. interval: null, //定时器
  8. socket: null, //socket
  9. }
  10. },
  11. mounted() {},
  12. methods: {
  13. initSocket() {
  14. /**主流浏览器都支持 webSocket 通信,但建议还是要判断*/
  15. if ("WebSocket" in window) {
  16. if (this.socket) {
  17. this.socket.close();
  18. }
  19. /**创建 web socket 实例
  20. * 如果连接失败,浏览器控制台报错,连接失败
  21. * 前缀 ws:// 必须正确,weChatInteract 是应用名称,webSocket/shake.action 是后台访问路径
  22. * */
  23. let url = `ws://192.168.2.15:8080/msg`;
  24. this.socket = new WebSocket(url);
  25. let _this = this;
  26. /**onopen:服务器连接成功后,自动触发*/
  27. this.socket.onopen = function() {
  28. this.interval = setInterval(function() {
  29. /** Web Socket 已连接上,使用 send() 方法发送数据*/
  30. let data = {};
  31. data.lon = lc.longitude;
  32. data.lat = lc.latitude;
  33. console.log(data)
  34. _this.socket.send(JSON.stringify(data))
  35. console.log("服务器连接成功,并发送数据到后台...");
  36. },30000)
  37. }
  38. /**服务器发送数据后,自动触发此方法,客户端进行获取数据,使用 evt.data 获取数据*/
  39. this.socket.onmessage = function(msg) {
  40. if (msg.data && msg.data != 'messageCenter login success') {
  41. // let message = JSON.parse(msg.data);
  42. console.log(message,'=> 接收到服务器数据')
  43. }
  44. }
  45. /**客户端与服务器数据传输错误时触发*/
  46. this.socket.onerror = function (evt) {
  47. console.log("客户端 与 服务器 数据传输错误...");
  48. };
  49. /**web Socket 连接关闭时触发*/
  50. this.socket.onclose = function(e) {
  51. console.log("web scoket 连接关闭...");
  52. if (this.interval) {
  53. clearInterval(this.interval);
  54. }
  55. setTimeout(function() {
  56. _this.initSocket();
  57. },5000)
  58. }
  59. } else {
  60. console.log("浏览器不支持 WebSocket!");
  61. }
  62. },
  63. },
  64. </script>

参考链接:

websocket的基础使用,心跳机制,断线重连_websocket断开后怎么自动连接-CSDN博客

关于WebSocket的心跳重连机制(详解)_websocket 心跳-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/770588
推荐阅读
相关标签
  

闽ICP备14008679号