聊天室(Websocket+Node)

文章目录


前言

使用Websocket+Node实现一个简单的聊天室的功能,以及包含保持websocket长时间连接永不断开的两种方法


一、Websocket是什么?

WebSocket是一种网络通信协议,是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket协议基于TCP协议实现,包含初始的握手过程,以及后续的多次数据帧双向传输过程。其目的是在WebSocket应用和WebSocket服务器进行频繁双向通信时,可以使服务器避免打开多个HTTP连接进行工作来节约资源,提高了工作效率和资源利用率。

二、使用步骤

1.服务端代码 

npm install koa
npm install ws
npm install koa-static
var Koa = require('koa');
const http = require('http');
const WebSocket = require('ws');
const path = require('path');
const serve = require('koa-static');

const app = new Koa(); // 初始化koa应用
app.use(serve(path.join(__dirname, '.'))); // 提供静态文件
const server = http.createServer(app.callback()); // 创建http服务器

let clientNames = ['小明', '小红', '小军', '小王']
const wss = new WebSocket.Server({ server }); // 创建 WebSocket 服务器

// 监听WebSocket连接
wss.on('connection', (ws) => {
  ws.clientName = clientNames.pop();
  console.log(ws.clientName + 'contect');
  
  // 监听客户端发送的消息
  ws.on('message', (message) => {
    wss.clients.forEach(client => {
      if(client.readyState !== WebSocket.OPEN) return
      
      if(message == 'hello') {
        client.send('收到,hello')
      }else {
        client.send(`${ws.clientName == client.clientName ? '我' : ws.clientName}:${message}`)
      }
    })
  })

  // 监听客户端断开连接
  ws.on('close', () => {
    console.log(`${ws.clientName} 断开连接!`);
  })
})

const PORT = 5500
server.listen(PORT, () => {
  console.log('5500端口连接上了---');
})

2.客户端代码

保持websocket长时间连接永不断开的两种方法

  • 方式一:定期发送心跳包

客户端代码

timeoutObj = setTimeout(() => {
        console.log('发送信息,重新连接----');
        socket.send('hello')
      }, 3000);

服务端代码

ws.on('message', (message) => {
    wss.clients.forEach(client => {
      if(client.readyState !== WebSocket.OPEN) return
      
      if(message == 'hello') {
        client.send('收到,hello')
      }else {
        client.send(`${ws.clientName == client.clientName ? '我' : ws.clientName}:${message}`)
      }
    })
  })
  • 方式二:捕获关闭连接事件并重连
socket.onclose = () => {
      console.log('断开连接!');
      // 方式一:
      setTimeout(() => {
        socket = new WebSocket(url);  // 重新连接
      }, 1000);  // 1秒后重连
    }
  • 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>聊天室</h1>
  <ul id="messages"></ul>
  <input type="text" id="messageInput" autocomplete="off" />
  <button id="sendBtn">发送</button>

  <script>
    const url = 'ws://localhost:5500'
    const socket = new WebSocket(url)

    // 方式二:
    let timeoutObj = null;
    // 开启心跳
    const start = () => {
      clearTimeout(timeoutObj);
      // serverTimeoutObj && clearTimeout(serverTimeoutObj);
      timeoutObj = setTimeout(() => {
        console.log('发送信息,重新连接----');
        socket.send('hello')
      }, 3000);
    };
    const reset = () => {
      // 重置心跳 清除时间
      clearTimeout(timeoutObj);
      // 重启心跳
      start();
    };

    socket.onopen = () => {
      console.log('连接成功!')
      start(); // 开启心跳
    };
    socket.onclose = () => {
      console.log('断开连接!');
      // 方式一:
      // setTimeout(() => {
      //   socket = new WebSocket(url);  // 重新连接
      // }, 1000);  // 1秒后重连
    }
    socket.onerror = (err) => console.log('连接错误:'+err);

    // 当收到服务器消息时触发
    socket.onmessage = (e) => {
      const { data } = e
      if (data === '收到,hello') {
        reset();
        return;
      }else {
        const li = document.createElement('li')
        li.textContent = data
        document.getElementById('messages').appendChild(li)
      }
    }

    const sendBtn = document.getElementById('sendBtn')
    sendBtn.addEventListener('click', ()=> {
      const msgInput = document.getElementById('messageInput')
      const msg = msgInput.value;
      if(msg) {
        socket.send(msg)
        msgInput.value = ''
      }
    })
  </script>
</body>
</html>

3.成果展示

  • 页面不刷新

  • 页面刷新(心跳机制成果展示)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了如何使用websocket实现一个简单聊天室的功能,欢迎各位大佬们多多指点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值