前端WebSocket

websocket实际项目开发中客户端(前端)使用websockect主要实现的功能是发送和接收信息而服务端实现接收、转发(负责两个客户端通信类似于一个通信基站)、发送消息功能。

项目中用到的相关技术vue3、vite、js(要通过WebSocket构造函数,创建WebSocket对象)、node.js、ws(是nodejs的一个WebSocket库,可以用来创建服务)

websocket服务端以node.js中使用为例(实际项目开发中可使用其他后端语言如java、python等)

创建相关文件目录

2c84f986c8214042b37a2cd69a302617.png

server.js代码

//服务(服务类似于一个水库)和链接(类似于一根根链接水库和用户的管道)
//这样的话管道就会有等多根(也就是链接会有多条如a用户和服务的链接和b用户和服务的链接)
const webscoket = require('ws')
const url = require('url')
let webScoketServer = new webscoket.Server({port: '8000'}) //创建服务 

//ws 是管道
let pool = new Map() //可能有多个用户链接 所以有多个管道 所以需要存储我们有那些管道链接
let idList = ['1','2']
//监听webScoketServer的长连接
webScoketServer.on('connection',(ws,req)=> {
    let id = url.parse(req.url,true).query.id; //获取用户id
    let token = req.headers['sec-websocket-protocol'] //获取用户token
    console.log(id);
    console.log(token);
    if(idList.indexOf(id) === -1) { //判断用户是否存在
        ws.send(JSON.stringify({
            type:'error',
            msg: 'id不正确'
        }))
        ws.close()
    }
    pool.set('connection'+id,ws) //存储相应的链接
    //针对链接进行监听
    ws.on('message',(msg)=> {
        console.log(msg.toString())
        ws.send(JSON.stringify(
            {
                type: 'msg',
                msg:'收到' + msg.toString()
            }
        ))
    })
    //关闭
    ws.on('close',()=> {

    })
    //错误
    ws.on('error',()=> {
        
    })
    //发送消息
    ws.send(JSON.stringify({a:123444}))

})

上面的代码我们用node.js创建了一个websocket服务 

websocket客户端以vue中使用为例

创建相关文件目录

1007c109513040fcbc06a344f9eadda6.png

App.vue文件

<template>
  <div>webSocket</div>
  <div>
    用户1
    <input v-model="inputValue" />
    <button @click="sendMsg">发送</button>
    <button>关闭</button>
  </div>
</template>

<style scoped></style>

效果

72d0fbdcdfb04b6da58e4dda283dde82.png

发送按钮绑定自定义事件sendMsg()

<script setup>
import { ref } from 'vue'
let inputValue = ref('')
function sendMsg() {
  client.send(inputValue.value)
}
</script>

连接创建好的webSocket服务

client = new WebSocket('ws://localhost:8000?id=1', ['afdsfsdfdsffsdf'])

通过webSocket提供的事件触发相关功能

close(关闭)

error (错误)

message (接收消息)

open (连接)

  //也可以用addEventLister监听
  client.onopen = () => {
    clearTimeout(reconnentTimer)
    headerBeat() //连接上后就开启心跳检测
    console.log('连接上了')
  }

  client.onmessage = (msg) => {
    //后端有消息
    console.log(JSON.parse(msg.data))
  }

  client.onclose = () => {
    reconnect()
    console.log('close')
  }

  client.onerror = () => {
    tryTime += 1
    reconnect()
    console.log('error')
  }

这里我将连接和监听相关事件封装成了一个方法

const initWebSocket = () => {
   client = new WebSocket('ws://localhost:8000?id=1', ['afdsfsdfdsffsdf'])
  //也可以用addEventLister监听
  client.onopen = () => {
    clearTimeout(reconnentTimer)
    headerBeat() //连接上后就开启心跳检测
    console.log('连接上了')
  }

  client.onmessage = (msg) => {
    //后端有消息
    console.log(JSON.parse(msg.data))
  }

  client.onclose = () => {
    reconnect()
    console.log('close')
  }

  client.onerror = () => {
    tryTime += 1
    reconnect()
    console.log('error')
  }
}

基本功能实现后为了保证websocket连接的一个持续效果和避免websocket服务因为网络或其他原因给我们断开连接所以我们还要实现定时重连和心跳检测的功能

定时重连实现

//websocket重连方法 
/* 
  重连不可能永远都进行重新连接那样的话触发的就太频繁了 所以需要一个定时器
*/
const reconnect = () => {
  //清除定时器
  clearTimeout(reconnentTimer)
  //用一个定时器避免频繁重连
  if(tryTime > maxTime) { //重连次数超过3次就不再重连
     alert('重连次数超过3次,请联系管理员!')
     clearTimeout(reconnentTimer)
     clearInterval(headerBeatTimer)
     return
  }
  reconnentTimer = setTimeout(() => {
    initWebSocket()
  }, 2000)
}

心跳检测实现

//webSockte 心跳检测
const headerBeat = () => {
  clearInterval(headerBeatTimer)
  headerBeatTimer = setInterval(()=> {
    client.send(JSON.stringify({
      type: 'headerBeat',
      msg: 'test'
    }))
  },3000)
}

App.vue完整代码

<script setup>
import { ref } from 'vue'
let inputValue = ref('')
let maxTime = 3 //重连最大的连接次数
let tryTime = 0 //重连后出错的次数
let reconnentTimer //重连定时器
let client
let headerBeatTimer //心跳定时器
//建立和webSocket服务的链接

//webSocket不可能让所有人随便连接,所以我们需要携带token或者id
//心跳检测 定期向websocket服务发送消息维持心跳是为了避免websocket给我们断开连接
//定时重连 如果连接中断或者出错我们需要重新连接保证websocket连接的一个持续效果
/* 
1.直接带在url的query
2.带在请求头上
3.cookie
*/
const initWebSocket = () => {
   client = new WebSocket('ws://localhost:8000?id=1', ['afdsfsdfdsffsdf'])
  //也可以用addEventLister监听
  client.onopen = () => {
    clearTimeout(reconnentTimer)
    headerBeat() //连接上后就开启心跳检测
    console.log('连接上了')
  }

  client.onmessage = (msg) => {
    //后端有消息
    console.log(JSON.parse(msg.data))
  }

  client.onclose = () => {
    reconnect()
    console.log('close')
  }

  client.onerror = () => {
    tryTime += 1
    reconnect()
    console.log('error')
  }
}

//websocket重连方法 
/* 
  重连不可能永远都进行重新连接那样的话触发的就太频繁了 所以需要一个定时器
*/
const reconnect = () => {
  //清除定时器
  clearTimeout(reconnentTimer)
  //用一个定时器避免频繁重连
  if(tryTime > maxTime) { //重连次数超过3次就不再重连
     alert('重连次数超过3次,请联系管理员!')
     clearTimeout(reconnentTimer)
     clearInterval(headerBeatTimer)
     return
  }
  reconnentTimer = setTimeout(() => {
    initWebSocket()
  }, 2000)
}

//webSockte 心跳检测
const headerBeat = () => {
  clearInterval(headerBeatTimer)
  headerBeatTimer = setInterval(()=> {
    client.send(JSON.stringify({
      type: 'headerBeat',
      msg: 'test'
    }))
  },3000)
}

function sendMsg() {
  client.send(inputValue.value)
}

initWebSocket()
</script>

<template>
  <div>webSocket</div>
  <div>
    用户1
    <input v-model="inputValue" />
    <button @click="sendMsg">发送</button>
    <button>关闭</button>
  </div>
</template>

<style scoped></style>

实现效果

cf13e5fe01de4bfa8a108e88da0fa55d.png a1e0cfb61e0c4d76a690f369fd0a389d.png

代码地址

司徒飞/vue-websockethttps://gitee.com/situ_fei/vue-websocket.git
司徒飞/vue-websocket-serverhttps://gitee.com/situ_fei/vue-websocket-server.git

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值