Node WebSocket 聊天室

在线演示

开始

npm init -y
npm i ws

代码

app.js
ws

// 1. 客户端建立连接,先同步聊天记录
// 2. 接收到客户端发来的消息,将新消息通知所有已建立连接的客户端
const WebSocket = require('ws');
const WebSocketServer = WebSocket.Server;
let charList = []; // 保存所有的聊天记录
const wss = new WebSocketServer({
    port: 3000
});
wss.on('connection', function (ws) {
    // 新连接同步聊天记录
    ws.send(JSON.stringify(charList), (err) => {
        if (err) {
            console.log(`[SERVER] error: ${err}`);
        }
    }); 
    ws.on('message', function (message) {
        console.log(`[SERVER] Received: ${message}`);
        let data = JSON.parse(message);
        charList.unshift(data);
        publishMessage(); // 给所有连接发布新消息
        
    })
});
function publishMessage() {
    // 所有建立的连接的客户端会保存在wss.clients
    for (let item of wss.clients.values()) {
        item.send(JSON.stringify(charList), (err) => {
            if (err) {
                console.log(`[SERVER] error: ${err}`);
            }
        });
      }
}

index.html
webSocket API

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <title>聊天室</title>
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <style>
      .container {
            width: 1120px;
            margin: 20px auto;
          }
            .username {
              font-size: 16px;
            }
            .content {font-size: 14px;}
            .g-mt-10 {margin-top: 10px;}
            .date {
              color: #ccc;
              font-size: 12px;
            }
        </style>
  </head>
  <body>
    <div id='app'>
      <div class="container">
        <el-card class="box-card" shadow='never' :body-style="{height: '300px',overflow: 'auto'}">
          <div slot="header" class="clearfix">
            <span>聊天窗口</span>
          </div>
          <div v-for="user in charList" :key="user.name" class="g-mt-10">
            <p class='date'>{{user.date}}</p>
            <div class='username'>{{user.name}}</div>
            <el-tag type="info">{{user.content}}</el-tag>
          </div>
        </el-card>
        <el-form :inline="true" class='g-mt-10'>
          <el-form-item label="用户名">
            <el-input v-model="formData.name" placeholder="用户名"></el-input>
          </el-form-item>
          <el-form-item label="内容">
            <el-input v-model="formData.content" placeholder="内容"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmit">发送</el-button>
          </el-form-item>
        </el-form>
      </div>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <script>
      let vm = new Vue({
        el: "#app",
        data: {
          charList: [],
          formData: {
            name: '',
            content: '',
          },
          ws: '',
        },
        methods: {
          onSubmit() {
            this.formData.date = new Date().toLocaleString();
            this.ws.send(JSON.stringify(this.formData));
          }
        },
        created() {
          this.ws = new WebSocket('ws://localhost:3000');
          this.ws.onmessage = function(res) {
            console.log(res)
            vm.charList = JSON.parse(res.data)
          };
        }
      })
    </script>
  </body>
</html>

运行

node app.js
用index.html 发送消息, 可以用多个浏览器打开模仿多用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值