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