TCP聊天室
关于怎么通过命令行,以客户的身份用命令行在本机连接启动的服务器,请看上一篇文章
链接:创建TCP服务器
首先可以从实例化服务器、监听必要事件、绑定端口监听开始:
// 实例化服务器对象
const net = require('net');
const server = net.createServer();
// 错误处理
server.on('error', (err) => {
console.log("警告!出现错误:" + err.message);
})
// 关闭通知
server.on('close',()=>{
console.log("服务器已关闭!聊天结束!");
})
// 绑定端口监听
server.listen(1234);
从连接中读取数据
通过data事件监听传入数据:
// 实例化服务器对象
const net = require('net');
const server = net.createServer();
let man = 0;
// 错误处理
server.on('error', (err) => {
console.log("警告!出现错误:" + err.message);
})
// 关闭通知
server.on('close', () => {
console.log("服务器已关闭!聊天结束!");
})
/**
* 监听传入的数据
* */
server.on('connection', (socket) => {
man++;
console.log(`目前共${man}人在聊天室!`);
socket.on('data', (data) => {
})
socket.on('close',()=>{
man--;
socket.write("有人退出聊天室");
})
})
// 绑定端口监听
server.listen(1234);
聚合客户端
需要向所有用户广播聊天数据,所以先要把所有连接统一管理:
let sockets = [];
server.on('connection', (socket) => {
man++;
console.log(`目前共${man}人在聊天室!`);
sockets.push(socket);
socket.on('data', (data) => {
// socket.write(data);
})
socket.on('close',()=>{
man--;
socket.write("有人退出聊天室");
})
})
广播数据
socket.on('data', (data) => {
sockets.forEach((item, index, arr) => {
if(item !== socket) {
// 如果不是自己,那么就需要广播数据
// 自己写的东西本机端可以看得到,广播会造成重复
item.write(data);
}
})
})
删除已关闭连接
socket.on('close', () => {
man--;
console.log("有人退出聊天室");
console.log("someone out");
const index = sockets.indexOf(socket);
sockets.splice(index, 1);
})
小结
综合上面的,整套代码如下:
// 实例化服务器对象
const net = require('net');
const server = net.createServer();
let man = 0;
// 错误处理
server.on('error', (err) => {
console.log("警告!出现错误:" + err.message);
})
// 关闭通知
server.on('close', () => {
console.log("服务器已关闭!聊天结束!");
})
/**
* 监听传入的数据
* */
let sockets = [];
server.on('connection', (socket) => {
man++;
console.log(`目前共${man}人在聊天室!`);
sockets.push(socket);
socket.on('data', (data) => {
sockets.forEach((item, index, arr) => {
if (item !== socket) {
// 如果不是自己,那么就需要广播数据
// 自己写的东西本机端可以看得到,广播会造成重复
item.write(data);
}
})
})
socket.on('close', () => {
man--;
console.log("有人退出聊天室");
const index = sockets.indexOf(socket);
sockets.splice(index, 1);
})
})
// 绑定端口监听
server.listen(1234);
TCP服务器会在其生命周期内发射一些事件,即在被绑定到某个端口上时会发射“监听”事件,被关闭时会发射“关闭”事件,而出现错误时会发射“错误”事件。还可以监听“连接”事件,该事件会在新客户端连接时出现。连接事件会向你提交一个socket对象, socket对象既是可渎流又是可写流,可以用该对象来监听数据、发送数据、终止连接,甚至可以将连接数据传入另一个流中,反过来也可以将一个可读流传入连接。
socket对象允许你使用socket.pause()和socket…resume()控制它的流程,还允许你对它的些参数进行微调。例如,可以在连接空闲一段时间时关闭它、频繁发送保持活跃数据包,或者打开或关闭Nagle算法。
此外,还可以创建处理大量连接的TCP服务器,客户端使用这个服务器按照某种方式彼此之间进行通信,例如本章创建的聊天服务器示例。