本文介绍: 目前很多项目需要用到websocket功能简单讲解一下这个功能简单来说就是,以往我们请求只能前台后台发但是如果我们遇到比如类似聊天一样的功能,别人发信息给我。我们处理起来很麻烦,当然也有办法,就是我们前端设置定时器定时请求后台拿到别人发给我的信息。但是很明显,这不是一个好办法,如果一秒一请求,那服务器顶不住,毕竟用户不是你一个。如果间隔时间久了,那别人发个信息给你,你都半天看不到,那还有人用你的软件吗。所以这时候出现websocket

前言

目前很多项目需要用到websocket功能
简单的讲解一下这个功能
简单来说就是,以往我们发请求只能前台给后台发
但是如果我们遇到比如类似聊天一样的功能,别人发信息给我。
我们处理起来很麻烦,当然也有办法,就是我们前端设置定时器
定时请求后台拿到别人发给我的信息
但是很明显,这不是一个好办法,如果一秒一请求,那服务器顶不住,毕竟用户不是你一个
如果间隔时间久了,那别人发个信息给你,你都半天看不到,那还有人用你的软件吗。
所以这时候就出现websocket。他可以前端后端建立长链接。保持通信状态
不需要前端发请求,后端可以自己把别人发来的信息推送到你前台。这就是方便多了。

看了网上很多人的帖子都是只有单独的,所以我这里再开一个前后端都有的websocket模板,可以复制即用,后端采用node.js这样方便前端的小伙伴看得懂。而且很简单操作,复制了就可以自己测试websocket功能,不需要依靠公司后端了。

效果图

心跳后端返回ok
在这里插入图片描述
心跳
在这里插入图片描述
发送的信息后端返回给我了。
在这里插入图片描述
心跳重连机制,如果链接失败或者错误,一直重连,直到链接成功为止
在这里插入图片描述

前端代码

vue直接复制

<template>
  <!-- websocketceshi -->
  <div class="layout">
    <div style="margin:20px;font-size:20px">websocket连接模板 有心跳重连机制</div>
    <div class="msgBody">
      <p v-for="(item, index) in msg" :key="index">{{ item }}</p>
    </div>
    <input
      v-model="inputMsg"
      style="width: 200px; height: 30px; margin-top: 20px"
    />
    <button @click="sendMessage" style="width: 100px; height: 30px">
      发送
    </button>
    <button @click="msg = []" style="width: 70px; height: 30px">清空</button>
  </div>
</template>

<script>
export default {
  name: "LayOut",
  data() {
    return {
      ws: null, //建立的连接
      lockReconnect: false, //是否真正建立连接
      timeout: 10 * 1000, //30秒一次心跳
      timeoutObj: null, //心跳心跳倒计时
      serverTimeoutObj: null, //心跳倒计时
      timeoutnum: null, //断开 重连倒计时
      wsUrl: "ws://localhost:8888", //后台websocket连接地址
      msg: [], //信息列表
      inputMsg: "", //输入
    };
  },
  created() {
    this.initWebpack();
  },
  beforeDestroy() {
    // 离开页面关闭连接
    this.ws.close();
    // 清除时间
    clearTimeout(this.timeoutObj);
    clearTimeout(this.serverTimeoutObj);
  },
  methods: {
    // 初始化websocket链接
    initWebpack() {
      this.ws = new WebSocket(this.wsUrl);
      this.ws.onopen = this.onopen;
      this.ws.onmessage = this.onmessage;
      this.ws.onclose = this.onclose;
      this.ws.onerror = this.onerror;
    },
    //重新连接
    reconnect() {
      var that = this;
      if (that.lockReconnect) {
        return;
      }
      that.lockReconnect = true;
      //没连接上会一直重连,设置延迟避免请求过多
      that.timeoutnum &amp;&amp; clearTimeout(that.timeoutnum);
      that.timeoutnum = setTimeout(function () {
        that.initWebpack(); //新连接
        that.lockReconnect = false;
      }, 5000);
    },
    //重置心跳
    reset() {
      var that = this;
      clearTimeout(that.timeoutObj); //清除心跳倒计时
      clearTimeout(that.serverTimeoutObj); //清除超时关闭倒计时
      that.start(); //重启心跳
    },
    //开启心跳
    start() {
      var self = this;
      self.timeoutObj &amp;&amp; clearTimeout(self.timeoutObj); //心跳倒计时如果有值就清除掉,防止重复
      self.serverTimeoutObj &amp;&amp; clearTimeout(self.serverTimeoutObj); //超时关闭倒计时如果有值就清除掉,防止重复
      //然后从新开一个定时器
      self.timeoutObj = setTimeout(function () {
        //这里通过readyState判断链接状态,有四个值,0:正在连接,1:已连接,2:正在断开,3:已经断开或者链接成功
        if (self.ws.readyState == 1) {
          //如果连接正常,给后天发送一个值,可以自定义然后后台返回我们一个信息,我们接收到后会触发onmessage方法回调
          self.ws.send("ping");
        } else {
          //如果检测readyState不等于1那也就代表不处在链接状态,那就是不正常的,那就调用重连方法
          self.reconnect();
        }
        //从新赋值一个超时计时器这个定时器作用:当你触发心跳的时候可能出现一个情况,后台崩了,前台发了个心跳,没有回应,就不会触发onmessage方法
        //所以我们需要在这个心跳发送出去了后,再开一个定时器用于监控心跳返回时间比如10秒,那么10秒内如果后台回我了,触发onmessage方法,自然就会把心跳时间和超时倒计时一起清空
        //也就不会触发这个关闭连接,但是如果10秒后还是没有收到回应,那么就会触发关闭连接,而关闭连接方法内又会触发重连方法循环就走起来了。
        self.serverTimeoutObj = setTimeout(function () {
          //如果超时了就关闭连接
          self.ws.close();
        }, self.timeout);
      }, self.timeout);
    },
    //连接成功
    onopen() {
      console.log("连接成功");
      if (this.ws.readyState == 1) {
        //如果连接正常,给后天发送一个值,可以自定义,然后后台返回我们一个信息,我们接收到后会触发onmessage方法回调
        this.ws.send("链接成功后先发给后台的信息");
      }
      this.start(); //链接成功后开启心跳
    },
    //接受后台信息回调
    onmessage(e) {
      /**这里自己业务逻辑代码**/

      this.msg.push(e.data);
      console.log("收到后台信息");
      this.reset(); //收到服务器信息,心跳重置
    },
    //关闭连接回调
    onclose(e) {
      console.log("连接关闭");
      this.reconnect(); //重连
    },
    //连接异常回调
    onerror(e) {
      console.log("出现错误");
      this.reconnect(); //重连
    },
    //发送消息
    sendMessage() {
      this.ws.send(this.inputMsg); //把前台的信息发给后台(可以跟后端商量传什么数据结构,一般不是这样简单的一个字符串,都是json格式的)
      this.inputMsg = "";
    },
  },
};
</script>
<style scoped>
.layout {
  position: relative;
  width: 100%;
  height: 100%;
}
.msgBody {
  width: 500px;
  height: 300px;
  border: 1px solid rgb(95, 79, 79);
  overflow: auto;
}
</style>


后端部分项目创建

没有下载node下载一下,没有淘宝镜像的可以下载一下淘宝镜像,方便后面下载。

1.安装node.js,自行官网下载,前端人员应该都有下载node。如果要看是否下载直接cmd输入 nodev查看版本
2.安装cnpm 安装命令npm install -g cnpmregistry=https://registry.npm.taobao.org

查看命令cnpmv

然后按照步骤来:
1,创建一个文件夹,然后在里面写一个文件名字expressrun.js这个代码复制进去就行了,这个代码包含getpost请求,以及websocket。所以前端小伙伴也可以用这个后台测试一下接口

var express = require("express"); //导入express  (下载)
var app = express();
var bodyParser = require("body-parser"); //导入body-parser  (下载)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));

// 跨域设置
var allowCrossDomain = function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*'); //自定义中间件设置跨域需要的响应头。
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE'); //允许任何方法
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,X-Session-Token'); //允许任何类型
    next();
};
app.use(allowCrossDomain);

//模拟信息
dataInfo = [
    { name: "苹果", count: 0, price: 10.01, check: false, },
    { name: "桃子", count: 0, price: 22.11, check: false, },
    { name: "橘子", count: 0, price: 8.12, check: false, },
]
//get方法  前台请求地址http://127.0.0.1:3000/list/fruitsData
app.get('/list/fruitsData', (req, res) => {
    res.status(200),
        res.send({ code: 200, describe: "success", data: dataInfo })
})

//post方法  前台请求地址http://127.0.0.1:3000/user/login
app.post('/user/login', (req, res) => {
    var { username, password } = req.body
    console.log(req.body);
    if (username != "xq" || password != "xq123") {
        return res.send({ code: 404, describe: "用户名密码正确" })
    } else {
        return res.send({ code: 200, describe: "success", data: { username, password } })
    }
})

//websocket
const WebSocketServer = require('ws').Server

const wss = new WebSocketServer({ port: 8888 }) //服务端口8888
var player = new Array()
console.log('创建ws服务', 'ws://localhost:8888')
// 创建连接
wss.on("connection", ws => {
    id = gid();
    player.push(id)
    console.log("新客户端已连接")
    // 接收client 数据
    ws.on("message", data => {
        //前台传ping就返回ok
        if (data == 'ping') {
            ws.send('ok')
            return
        }
        //群发
        wss.clients.forEach(s => {
            if (s.readyState == 1 &amp;&amp; s.socketIdxos != id) {
                s.send(data)
            }
        })
    })
    ws.on("close", () => {
        console.log("websocket server: 客户端已关闭连接")
        player = new Array()
    })
    ws.onerror = function () {
        console.log("websocket server: 出错了")
    }
})
//给用户设定一个id
function gid() {
    var id = Math.floor(Math.random() * (99999999 - 10000000 + 1)) + 10000000
    var have = false;
    for (var i = 0; i < player.length; i++) {
        if (player[i] == id.toString()) {
            have = true;
            break;
        }
    }
    if (have) {
        gid();
    } else {
        return id;
    }
}


const port = process.env.PORT || 3000  //端口
const host = process.env.HOST || '127.0.0.1' //地址
//运行
app.listen(port, host, () => {
    console.log(`Server is running on http://127.0.0.1:3000`);
});

2,安装依赖 cnpm install -S express body-parser
3,安装package.json 安装命令 npm init -y

然后就可以了。直接启动就行了。
启动方式简单

启动方式:和前端启动方式一样,这里一般默认的是start 那你启动npm run start
但是我改成了dev,这是我的习惯,所以我的启动方式就是npm run dev
然后当下面出现了Server is running on http://127.0.0.1:3000这句话就代表后台启动成功正在运行了,这句话是log出来的,可以自己别的也行。
如果你想结束运行,也是和前台一样ctrl+c按两下就行。
在这里插入图片描述
这是项目结构
在这里插入图片描述

原文地址:https://blog.csdn.net/seeeeeeeeeee/article/details/127323888

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44988.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注