一、服务端
socket服务端接受来自客户端的write内容(也可以理解成请求报文);然后广播给先有连接的所有客户端用户client
const net = require("net");
const clients = [];
const port = 9999;
var client = net.createServer(socket=> {
console.log(`server ${socket.remoteAddress} add in port ${port}`);
clients.push(socket); //保存连入的客户
//群聊数据处理
function broadcast(signal,clients){
let send = {
protocal: signal.protocol,
protocal: signal.from,
protocal: signal.message,
};
//遍历所有客户端发送
clients.forEach(client => {
client.write(JSON.stringify(send));
})
}
//接受客户端数据
socket.on("data", (chunk) => {
let signal = JSON.parse(chunk.toString().trim());
let protocol = signal.protocal;
switch(protocol) {
case "broadcast"://群聊
broadcast(signal,clients);
break;
case "p2p"://私聊
p2p(signal);
break;
default:
socket.write("到底私聊还是群聊,你告诉我啊。。。");
}
})
})
client.listen(port, (err) => {
if(err) {throw new Error("端口被占用,服务启动失败")};
console.log(`server is listened on port ${port}`);
})
二、客户端
const net = require("net");
const port = 9999;
const readline = require("readline");//用来读取输入行内容,api是有的,得找时间好好看看,据说可以逐行读取文件;
let rl = readline.createInterface(process.stdin, process.stdout);
rl.question("请输入聊天室用户名: "(name)=> {
name = name.trim();
//输入名字了就创建链接
let server = net.createConnection({port:port}, () => {
//接受服务端的返回内容
server.on("data", (chunk) => {
let receive = JSON.parse(chunk.toString().trim());
let protocol = receive.protocol;
switch(protocol) {
case "broadcast":
console.log("\n" + receive.protocal);
console.log(receive.from);
console.log(receive.message);
rl.prompt();
break;
//私聊
case "p2p":
.......//后面在写
}
})
rl.setPrompt(name + ">");
rl.prompt(); //将输入写入到命令行;
rl.on("line", (line) => {
let send = {
protocol: "broadcast",
from: name,
message: line.toString().trim(),
}
//发送输入的消息内容至服务端
server.write(JSON.stringify(send));
})
})
})
小结:群聊是将接受内容遍历发送给每个存储起来的socket客户端对象,而私聊,需要根据输入的内容判断,是向谁私聊,然后点对点进行单个socket数据传输;
**可以加入在线人数,增加error事件监听,监听下线人数,当所有连接成功发送,某一个客户端突然出现发送失败,就可以简单理解为下线(简单理解,距离怎么根据网络监听在线下线还不知道。。。。)
**这只是在命令行中进行测试的案例,所以使用了readline模块。可以在html文件中操作dom元素,增添输入框,模拟一个聊天室的功能;后续试试;
**越努力,越幸运,加油