在线演示
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 发送消息, 可以用多个浏览器打开模仿多用户