使用nodejs实现一个简易版聊天程序.client端package.json{ "name": "client", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.18.2" }}server.jsconst express = require("express");const path = require("path");const port = 4000;const app = new express();app.use(express.static(path.resolve(__dirname, "public")));app.listen(port, () => { console.log(`Client server run at ${port}.`);})public/index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .chat { display: flex; flex-direction: column; row-gap: 10px; } .row { display: flex; width: 400px; column-gap: 10px; } #display { width: 100%; height: 300px; background-color: white; border: 1px solid black; overflow-y: auto; } #input { height: 100px; width: 400px; } </style></head><body> <div class="chat"> <div class="row"> <input id="sender" type="text" placeholder="发送方" /> <button onclick="onConnect()">connect</button> <button onclick="onDisConnect()">disconnect</button> <button onclick="onClear()">clear</button> </div> <div class="row"> <textarea id="display" readonly></textarea> </div> <div class="row"> <textarea id="input" placeholder="发送消息"></textarea> <div> <input id="receiver" placeholder="接收方" /> <button onclick="onSend()">send</button> </div> </div> </div> <script> let senderDom = document.getElementById("sender"); let receiverDom = document.getElementById("receiver"); let inputDom = document.getElementById("input"); let displayDom = document.getElementById("display"); let websocketIp = "ws://localhost:4005?name="; let ws; function onConnect() { if (ws) { onDisplay(`You are already online.`); return; } let sender = senderDom.value; ws = new WebSocket(websocketIp + sender); ws.onopen = (e) => { clearDisplay(); onDisplay(`You are online.`); } ws.onclose = (e) => { onDisplay(`You are offline.`); ws = undefined; } ws.onmessage = (e) => { const obj = JSON.parse(e.data); const { type, data } = obj; if (type == "status") { const { user, status } = data; onDisplay(`${user} is ${status == 0 ? "offline" : "online"}.`); } else if (type == "message") { const { sender, message } = data; onDisplay(`${sender}:${message}`); } } } function onDisConnect() { if (!ws) { onDisplay(`You are offline,please connect first.`); return; } ws.close(); } function onClear() { clearDisplay(); } function onSend() { if (!ws) { onDisplay(`You are offline,please connect first.`); return; } let sender = senderDom.value; let receiver = receiverDom.value; let message = inputDom.value; let msg = JSON.stringify({ receiver: receiver, message: message }); ws.send(msg); onDisplay(`${sender}:${message}`); } //utils function onDisplay(value) { displayDom.value += value + "\n\n"; displayDom.scrollTop = displayDom.scrollHeight; } function clearDisplay() { displayDom.value = ""; } </script></body></html>server端package.json{ "name": "server", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.18.2", "ws": "^8.11.0" }}server.js/** * 数据结构 * get: * type message/status * data {sender,receriver,message}/{user,status: //0 offline 1 online} * * send: * {receiver,message}*/const MESSAGE_TYPE = { MESSAGE: "message", STATUS: "status",};const STATUS = { ONLINE: 1, OFFLINE: 0,}const Websocket = require("ws");const url = require("url");const port = 4005;const wss = new Websocket.Server({ port: port });wss.on("connection", (ws, req) => { const parameters = url.parse(req.url, true); ws.name = parameters.query.name; //notice all the client that somebody is login wss.clients.forEach(client => { //skip self if (client.name == ws.name) { return; } let msg = JSON.stringify({ type: MESSAGE_TYPE.STATUS, data: { status: STATUS.ONLINE, user: ws.name, } }); client.send(msg) }) ws.on("message", (e) => { const data = JSON.parse(e.toString()); const { receiver } = data; wss.clients.forEach(client => { if (client.name == receiver) { let msg = JSON.stringify({ type: MESSAGE_TYPE.MESSAGE, data: { ...data, sender: ws.name, }, }) client.send(msg); } }) }) ws.on("close", (e) => { wss.clients.forEach(client => { let msg = JSON.stringify({ type: MESSAGE_TYPE.STATUS, data: { status: STATUS.OFFLINE, user: ws.name, } }); client.send(msg) }) })})演示效果
