websocket的基础使用,心跳机制,断线重连

这篇具有很好参考价值的文章主要介绍了websocket的基础使用,心跳机制,断线重连。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

websoket出现的原因: 传统的http请求只能是由前端向后台发送一个请求,然后后台把结果返回给前端,前端再进行展示。这里就暴露了一个问题,就是通信只能由前端发起,而后台无法主动与前端通信。而websoket的出现就是为了解决这个问题,让前端可以主动联系后台,后台也可以主动联系前台。
应用场景: 相信大家都知道websoket的应用场景主要是用于即时通讯,比如QQ、微信即时通讯软件,同时在一些实时监控,需要即时暴露问题的地方也需要用到websoket,比如大屏可视化,需要及时的展现商品的成交数量。另外还有就是后台需要某个条件才能触发任务,在触发了任务时需要主动的告诉前端。

主流的技术

1.原生websocket
2.socket.io(推荐)

目前在websocket中应用比较多的就是这两个技术,一个是原生的websoket,另外一个socket.io是在原生websoket的基础上进行了封装了一层后的技术,让程序员更加的好用。

如何进行技术的选择:个人推荐最好还是使用ocket.io这个库, 原因就是更好用。但是很大的原因还是需要取决于后台的选择,如果后台选择了原生websocket,那么前端也需要使用原生websocket。如果后台对socket.io熟悉,那么前端也需要选择 socket.io,这是最好不过的,会让你们的开发更加的顺畅。

基础使用

1.websoket

// WebSocket构造函数,创建WebSocket对象
let ws = new WebSocket('ws://localhost:8888')

// 连接成功后的回调函数
ws.onopen = function (params) {
  console.log('客户端连接成功')
  // 向服务器发送消息
  ws.send('hello')
};

// 从服务器接受到信息时的回调函数
ws.onmessage = function (e) {
  console.log('收到服务器响应', e.data)
};

// 连接关闭后的回调函数
ws.onclose = function(evt) {
  console.log("关闭客户端连接");
};

// 连接失败后的回调函数
ws.onerror = function (evt) {
  console.log("连接失败了");
};


// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,这样服务端会抛异常。
window.onbeforeunload = function() {
    ws.close();
}  

如以上代码,基本上已经涵盖了原生ws的所有用法,包括原生ws的事件:open,Message,Error,Close四大事件,两个基本方法:send方法(用于发送数据),close方法(用于关闭连接)

解释:
open事件:websoket连接成功时会执行该方法(也叫做回调函数)
message事件:websoket在收到消息时会执行该方法,例如后台send一个数据给前端,前端收到后就会执行message方法。
error事件:websoket连接错误时会执行该方法,一般是用于处理ws错误的情况
close事件:websoket连接关闭后会执行该回调函数,一般用于处理错误或善后
send方法:websoket发送消息的方法
colse方法:主动关闭ws连接的方法

参考链接:websoket前端基本使用:https://blog.csdn.net/qq_17627195/article/details/128559926

2.socket.io

这里soket.io分为前端和后端,前端使用只需要使用socket.io-client这个库就ok了,如下图官网
image.png
引入:

import io from 'socket.io-client';

使用:


<template></template>
<script>
import io from 'socket.io-client';
export default {
  data(){
    return{
      sockets:null,
    }
  }
  mounted(){
    // 建立socket连接
    this.sockets = io('ws://localhost:8888')
    //监听
    this.sockets.on('connect', () => {
      //监听连接是否成功
      this.sockets.emit("news","这是发送事件的内容");
      console.log('connect');
    });
    this.sockets.on('disconnect', (reason) => {
      //断开连接时触发此事件
      console.log(reason);
    });
    this.sockets.on("connect_error", () => {
		  // 连接错误时触发该事件
       console.log('connect_error');
		});
    this.sockets.on('XXXX', (data) => {
      //监听后端返回事件,XXXX是与后端约定的字段
      console.log('XXXX',data);
    });
  }destroyed() {
    //断开连接,需要时再执行
    this.sockets.close()
  },
}
</script>


这里列出了socket.io的主要事件和方法(还有一些没有列出,需要的可以到官网查询)
主要事件有connect,disconnect,connect_error事件以及很重要的自定义消息事件。方法有on,emit,close方法
connect事件:socket.io连接成功后会执行该回调
disconnect事件:socket.io断开连接后会执行该回调
connect_error事件:socket.io连接错误时会执行该回调
自定义消息事件xxxx:socket.io在收到后台发送的xxxx事件后会执行xxxx的事件。这里的自定义消息事件,一定是前后端都需要一致的。比如后台向前端发送了(emit)事件A,内容为’aaaa’,则前端通过监听事件A,则能拿到后台的消息,一致的是事件A的名字。
on方法:监听各种事件
emit方法:用于发送消息
close方法:用于关闭socket.io的连接

参考链接:
1.官网:https://socket.io/docs/v4/client-socket-instance/
2.socket.io前端基本使用:https://blog.csdn.net/dragon_zjl/article/details/124793808

心跳机制和断线重连

心跳机制和断线重连方法出现的原因: 这里想说明的是websoket的基本使用其实是不难的,最主要还是需要去处理实际业务中会出现的问题,如果仅会基础使用的话,你将会面临以下几个问题:1.服务端挂了,半小时后服务重启成功了,但是发现websoket依然没有连接上来。 2.用户断网,断网之后又有网了,发现websoket在断网后断开了连接,但是在用户有网时却没有连接上来 3.在使用了nginx之后发现:websoket会自动断线,且连接不上来。

心跳机制简述:就是客户端每隔一段时间向服务端发送一个特有的心跳消息,每次服务端收到消息后只需将消息返回,此时,若二者还保持连接,则客户端就会收到消息,若没收到,则说明连接断开,此时,客户端就要主动重连,完成一个周期

断线重连简述:就是在用户断线或者服务端掉线之后,每隔一段时间重新new一个websoket实例的过程(new的过程就是连接的过程)。

实现代码(基础版-node后端):

const WebSocket = require("ws")
const wss = new WebSocket.Server({ port: 3000 })

wss.on("connection", (ws) => {
  console.log("有人连接进来了")
  // ws.on("message", (data) => {
  //   ws.send(data + "+九月九日忆山东兄弟")
  // })
  ws.on("error", () => {
    console.log("连接错误")
  })
  ws.on("close", () => {
    console.log("有人断开连接了")
  })
  ws.on("message", (e) => {
    console.log(e)
    const data = JSON.parse(e)
    console.log(data)
    switch (data.ModeCode) {
      case "message":
        console.log("收到消息" + data.msg)
        ws.send(e)
        break
      case "heart_beat":
        console.log(`收到心跳${data.msg}`)
        ws.send(e)
        break
    }
  })
})

实现代码(基础版-前端):

<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link>
      |
      <router-link to="/about">About</router-link>
      <div>
        <!-- {{ wsdata }} -->
      </div>
    </nav>
    <router-view />
  </div>
</template>

<script>
const ModeCode = {
  // websocket消息类型
  MSG: 'message', // 普通消息
  HEART_BEAT: 'heart_beat' // 心跳
};

export default {
  data() {
    return {
      ws: null,
      webSocketState: false, // webSocket的连接状态
      heartBeat: {
        // 心跳连接的时间设置
        time: 5 * 1000, // 心跳时间间隔
        timeout: 3 * 1000, // timeout:心跳超时间隔
        reconnect: 10 * 1000 // 断线重连时间
      },
      reconnectTimer: null // 断线重连时间器
    };
  },
  created() {
    this.connectWebSocket();
  },
  methods: {
    /*
     * 心跳初始函数
     * @param time:心跳时间间隔
     */
    startHeartBeat(time) {
      setTimeout(() => {
        this.ws.send(
          JSON.stringify({
            ModeCode: ModeCode.HEART_BEAT,
            msg: new Date()
          })
        );
        this.waitingServer();
      }, time);
    },
    // 延时等待服务端响应,通过webSocketState判断是否连线成功
    waitingServer() {
      this.webSocketState = false;
      setTimeout(() => {
        if (this.webSocketState) {
          this.startHeartBeat(this.heartBeat.time);
          return;
        }
        console.log('心跳无响应,已断线');
        try {
          this.ws.close();
        } catch (e) {
          console.log('连接已关闭,无需关闭');
        }
        this.reconnectWebSocket();
      }, this.heartBeat.timeout);
    },
    // 重连操作
    reconnectWebSocket() {
      this.reconnectTimer = setTimeout(() => {
        this.reconnectWs();
      }, this.heartBeat.reconnect);
    },
    connectWebSocket() {
      this.ws = new WebSocket('ws://localhost:3000');
      this.init();
    },
    init() {
      this.ws.addEventListener('open', () => {
        // eslint-disable-next-line spaced-comment
        this.webSocketState = true; //socket状态设置为连接,做为后面的断线重连的拦截器
        // eslint-disable-next-line no-unused-expressions
        this.heartBeat && this.heartBeat.time ? this.startHeartBeat(this.heartBeat.time) : ''; // 是否启动心跳机制
        console.log('开启');
      });
      this.ws.addEventListener('message', (e) => {
        const data = JSON.parse(e.data);
        switch (data.ModeCode) {
          case ModeCode.MSG: // 普通消息
            console.log('收到消息' + data.msg);
            break;
          case ModeCode.HEART_BEAT: // 心跳
            this.webSocketState = true;
            console.log('收到心跳响应' + data.msg);
            break;
        }
      });
      this.ws.addEventListener('close', (e) => {
        this.webSocketState = false; // socket状态设置为断线
        console.log('断开了连接');
      });
      this.ws.addEventListener('error', (e) => {
        this.webSocketState = false; // socket状态设置为断线
        this.reconnectWebSocket(); // 重连
        console.log('连接发生了错误');
      });
    },
    reconnectWs() {
      if (!this.ws) {
        // 第一次执行,初始化
        this.connectWebSocket();
      }
      if (this.ws && this.reconnectTimer) {
        // 防止多个websocket同时执行
        clearTimeout(this.reconnectTimer);
        this.ws.reconnectTimer = null;
        this.connectWebSocket();
      }
    }
  }
};
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

主要的代码逻辑:

1.在声明周期钩子函数created中进行连接ws,主要是去new出一个ws实例,以及为该实例注册事件。
2.在连接ws成功后会执行open的回调函数,在该回调函数中开启心跳,即定时向后端发送数据,如代码中,向后台每5秒发送一个心跳,并同时等待服务端的响应(waitingServer函数)。在waitingServer函数中将连接状态设置为false(假设没连接),如果此时后台是连接正常的,则会触发message的回调函数,将连接状态设置为true。而且waitingServer函数将会在3秒后进行检测连接的状态。如果3s后的状态正常,则继续发送心跳。但是如果不成功,那么就去关闭本次websoket连接,并触发重连操作。
image.png
3.在重连操作中,则是每隔10s进行一次初始化ws的操作。但是在初始化ws时,由于后台服务掉线/用户没网会触发ws的’error’事件,该事件的回调中又去触发重连操作,重连操作中又是去触发初始化ws的操作,所以形成了一次次的重连操作,直到连接上后台服务为止。
image.png
image.png

最后是模拟重连的截图

a.后台服务掉线
image.png
image.png
b.用户断网
image.png
image.png

最后

websocket心跳机制和断线重连的理解可能需要花费更多的时间,重点是需要自己去跑通代码并看其中的逻辑,我这里放的代码是完全没有抽取过的,属于新手比较容易看得懂的代码。如果追求更好的代码封装,可以看下下面这篇文章:
参考链接:心跳机制和断线重连:https://juejin.cn/post/6945057379834675230

这里放出本次demo的地址,可以下载下来自己去看。
demo地址:
node后台:https://github.com/rui-rui-an/wsnodeserver
前端:https://github.com/rui-rui-an/wswebcode文章来源地址https://www.toymoban.com/news/detail-455856.html

到了这里,关于websocket的基础使用,心跳机制,断线重连的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • websocket断线重连&&心跳检测

    封装websocket 实现断线重连跟心态检测,使用的typeScript去封装 在nodejs 安装ws库 代码如下(示例):  服务端实现ws 创建一个server.js 文件 运行ws服务   node .server.js  客户端实现websocket 创建一个socket.ts 文件 vue 页面使用 断开ws服务 断线  启动服务后 自动重连

    2024年01月19日
    浏览(39)
  • Unity-TCP-网络聊天功能(四): 消息粘包、心跳机制保活(心跳包)、断线重连

    bug1:下线后,如果发送多条消息,在客户端上线时,一瞬间接收到,效果如同粘包,需要拆包。举例,连续发送三条160长度消息,可能实际显示2条消息,原因,第三条消息和第二条消息粘包,第二条消息长度变为320,但是Receive方法没有考虑这个问题,相当于这段代码只运行

    2024年02月11日
    浏览(39)
  • C++ Qt TCP的心跳检测机制,断线重连技术,应用层代码重新实现

    目录 前言: 一、Qt直接启动本身的KeepAlive 二、在应用层自己实现一个心跳检测  三、自定义心跳代码实现: 完整客户端服务端工程下载: 共用的结构体相关头文件:         客户端部分核心代码:         服务端部分核心代码: 运行结果展示: 前两篇关于qt tcp 相关的,

    2024年02月05日
    浏览(44)
  • uniapp websocket机制 心跳 重连

    在开发程序过程中通信功能还是比较常用到的,本文主要介绍的是uniapp中websocket的使用 websocket建立连接后,断开、心跳机制重新链接的一个过程。 关于uni.connectSocket可仔细阅读uniapp官网中的uni.connetSocket以及连接socket创建的实例 SocketTask   具体代码如下:内有代码详细注解,

    2024年02月12日
    浏览(40)
  • java实现WebSocket客户端&&断线重连机制

    1、引入maven依赖(注意版本) 2、代码

    2024年02月16日
    浏览(49)
  • WebSocket心跳检测和重连机制

    心跳和重连的目的用一句话概括就是客户端和服务端保证彼此还活着,避免丢包发生。 websocket 连接断开有以下两证情况: 前端断开 在使用 websocket 过程中,可能会出现网络断开的情况,比如信号不好,或者网络临时关闭,这时候websocket的连接已经断开,而不同浏览器有不同

    2024年01月21日
    浏览(41)
  • Flutter:WebSocket封装-实现心跳、重连机制

    前言Permalink Flutter简介 Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Nat

    2024年02月10日
    浏览(53)
  • WebSocket实战之六心跳重连机制

    WebSocket应用部署到生产环境,我们除了会碰到因为经过代理服务器无法连接的问题(注:该问题可以通过搭建WSS来解决,具体配置请看 WebSocket实战之四WSS配置 ),另外一个问题就是外网环境不稳定经常会断开或者服务器重启或者网络中间服务器当发现一个长连接长时间没有

    2024年02月07日
    浏览(48)
  • Android中okhttp的websocket的详细使用方法(加断线重连)

    介绍之类的就不多讲了,懒得讲也未必有别人整理的清晰,直接上代码 使用:

    2024年02月15日
    浏览(35)
  • uniapp websocket 封装断线重连

     1.新建一个工具类js文件 2. 把我封装的代码复制进去 我是用uniapp 的api封装的 在外面也可以直接用uniapp的api操作 只有在开始调用连接需要用封装的方法调用 在需要使用封装的方法的页面 引入js     import {         websocetObj     } from \\\"@/API/websocket.js\\\"  完善重连 在app.vue的

    2024年02月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包