共计 4072 个字符,预计需要花费 11 分钟才能阅读完成。
应用 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.js
const 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)
})
})
})
演示成果
正文完