需求
- 创建一个可以多人即时通讯的聊天室。
- 用户加入时必须要设置昵称,且昵称不能相同。
- 用户加入成功打印出成功欢迎信息和当前在线人数,并通知聊天室内其他的人。
- 用户发送信息时,需要广播到所有的用户。
- 当某一用户离开时也需要通知到所有的用户。
效果演示
程序实现
服务端
//tcpServer.js
// 引入colors模块
require('colors');
// 引入net模块
const net = require('net');
// 在线计数器
var count = 0,
users = {};
// 创建服务
const serv = net.createServer((conn) => {
console.log('有用户进来了'.red);
// 用户欢迎信息
conn.write('\n你好!欢迎来到管子聊天室!'.rainbow);
// conn.write('\nOnline=>'.green + count);
conn.write('\n请输入你的昵称:'.red);
// 设置编码
conn.setEncoding('utf-8');
count++;
// 代表当前链接的昵称
let nickName;
// 接收处理用户数据
conn.on('data', (data) => {
// 第一次用户回复数据视为设置昵称
if (!nickName) {
// 判断昵称是否已被占用
if (users[data]) {
conn.write('\n该昵称已被占用,请重新设置:'.red);
return;
} else {
nickName = data;
users[nickName] = conn;
console.log(Object.keys(users));
// 发布用户加入广播
broadcast('\n欢迎 ' + nickName);
broadcast('\n当前在线=>'.green + count);
conn.write('\n欢迎 ' + nickName);
conn.write('\n当前在线=>'.green + count);
}
} else {
// 聊天消息
broadcast('\n' + nickName + data.split('\r')[0]);
}
});
// 监听用户离线
conn.on('close', (c) => {
console.log('有用户离开了'.red);
count--;
broadcast('\n离线=>'.red + nickName);
broadcast('\n当前在线=>'.green + count);
//将用户从中删除
delete users[nickName];
});
// 错误处理
conn.on('error', (err) => {
console.error(err);
});
// 用户广播
function broadcast(val) {
for (let i in users) {
if (i !== nickName) {
console.log(new String(i));
console.log(new String(nickName));
console.log(i == nickName);
users[i].write(val + ++sm);
}
}
}
});
serv.listen(3030, () => {
console.log('服务已启动'.yellow);
});
客户端
//引入net模块
const net = require('net');
//端口
const port = 3030;
//地址
const host = '127.0.0.7';
//链接tcp服务端
const client = net.connect(port, host);
//设置编码
client.setEncoding('utf-8');
//监听是否链接成功
client.on('connect', () => {
console.log('tcp服务器已连接');
});
//接收服务器数据
client.on('data', (data) => {
process.stdin.pause()
console.log(data);
//打开输入流
input();
});
//监听断开服务器
client.on('close', () => {
console.log('用户断开了服务器');
});
//错误处理
client.on('error', () => {
});
//启动输入流
function input() {
process.stdout.write('请输入');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.once('data', option);
}
//发送数据
function option(data) {
//关闭用户输入
process.stdin.pause()
let datas = data.split('\r')[0];
console.log(new String(datas));
if (datas == 'exit') {
//关闭与服务器的链接
client.end('再见,各位!')
} else {
//往服务器发送数据
client.write(datas);
}
}