websocket实现多用户一对一实时聊天

这个项目使用 Node.js 搭建了一个基于 WebSocket 的双向通信网页,支持实时更新在线人数和用户间的即时通讯。通过心跳机制处理连接断开和重连,动态获取在线用户列表,并在用户连接时通知其他用户。同时,结合 AJAX 和 WebSocket 实现了特定用户间的聊天信息获取和发送。

在线聊天模实现

项目是基于node.js服务器搭建的简易双向通信网页,实现了实时更新在线人数以及用户间即时通讯的功能。

1、websocket连接创建

基于后台websocket地址创建简易的连接,并且当websocket断开后自动重新连接。

let lockReconnect = false // 是否允许重新连接
let timeout = 1000 * 20 // 心跳间隔
let reTimeout = 1000 * 10 // 重连间隔
let timeoutTimer = null // 心跳定时器
let reTimeoutTimer = null // 重连定时器
let webSocket = null
let uid = new Date().getTime() // 图方便,将时间戳当作用户id
// 创建websocket连接
function createWebSocket () {
   
   
  let webSocket = new WebSocket('ws://localhost:5001/' + uid)
  webSocket.binaryType = 'arraybuffer';
  webSocket.onerror = function () {
   
   
    console.log('连接失败...')
    reConnect()
  }
  // websocket收到信息的处理逻辑
  webSocket.onmessage = function (event) {
   
   
    if (event.data) {
   
   
      let res = JSON.parse(event.data)
      console.log(res)
    }
  }
  webSocket.onclose = function (event) {
   
   
    console.log('连接已关闭...')
    console.log('websocket 断开: ' + event.code + ' ' + event.reason + ' ' + event.wasClean)
    reConnect()
  }
}
// 重连
function reConnect () {
   
   
  if (lockReconnect) {
   
   
    return
  }
  lockReconnect = true
  // 没连接上会一直重连,设置延迟避免请求过多
  reTimeoutTimer && clearTimeout(reTimeoutTimer)
  reTimeoutTimer = setTimeout(function () {
   
   
    createWebSocket()
    lockReconnect = false
  }, reTimeout)
}

2、基于websocket动态获取在线用户

想要实现实时获取在线用户列表,并且有用户连接上wesocket服务时,通知给其他在线用户。
服务器端

// 存储在线用户
let onlineUser = []
wss.on('connection', (ws, req, res) => {
   
   
// 获取当前连接websocket的用户uid
  let uid = req.url.substr(1)
  let index = onlineUser.findIndex(val => val.id === uid)
  if (index !== -1) {
   
   
    onlineUser[index].websocket = ws
  } else {
   
   
    onlineUser.push({
   
   
      websocket: ws,
      id: uid
    })

  }
  // 获取在线用户id数组
  let User = JSON.stringify({
   
   
    onlineUser: onlineUser.map(val => val.id),
    type: 'users'
  })
  // 通知所有在线用户有新用户上线
  onlineUser.forEach((client) => client.websocket.send(User))
})

用户端

// websocket收到信息的处理逻辑
    webSocket.onmessage = function (event) {
   
   
      if (event.data) {
   
   
        let res = JSON.parse(event.data)
        console.log(res)
        switch (res.type) {
   
   
          // 当消息为用户列表
          case 'users':
            userList.innerHTML = res.onlineUser.map(val => {
   
   
              if (val == uid) {
   
   
                return '<li>me:' + val + '</li>'
              } else {
   
   
                return '<li>' + val + '</li>'
              }
            }).join('')
            break
          default:
        }
      }
    }

3、基于ajax+websocket获取与某个用户的聊天信息

服务器端收到用户发送给另一个用户的消息后,遍历在线用户列表并匹配到接收消息的用户,将消息发送给所匹配到的用户。

ws.on('message', (msg) => {
   
   
    // 将收到的消息转成对象格式
    const buf = Buffer.from(msg)
    let notice = buf.toString('utf-8')
    let Notice = JSON.parse(notice)

    // 通知当前用户消息发送成功
    ws.send(JSON.stringify({
   
   
      msg: Notice.msg,
      type
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值