- 使用
net
模块:
- 在Node.js中,
net
模块是用于创建TCP服务器和客户端的基础模块。
- 以下是一个简单的TCP服务器示例,展示如何管理多个客户端连接:
const net = require('net');
const server = net.createServer((socket) => {
// 新客户端连接时触发
console.log('新客户端连接');
socket.on('data', (data) => {
// 处理客户端发送的数据
console.log('收到数据:', data.toString());
socket.write('已收到你的数据');
});
socket.on('end', () => {
// 客户端断开连接时触发
console.log('客户端断开连接');
});
});
server.on('error', (err) => {
throw err;
});
server.listen(8080, () => {
console.log('服务器监听在端口 8080');
});
- 连接管理和资源分配:
- 连接池:虽然上述简单示例没有使用连接池,但在更复杂场景下,可以使用连接池来管理客户端连接。例如,可以创建一个数组来存储所有连接的
socket
对象,然后通过维护这个数组来对连接进行统计、限制等操作。
const net = require('net');
const connectionPool = [];
const server = net.createServer((socket) => {
connectionPool.push(socket);
console.log('新客户端连接,当前连接数:', connectionPool.length);
socket.on('data', (data) => {
console.log('收到数据:', data.toString());
socket.write('已收到你的数据');
});
socket.on('end', () => {
const index = connectionPool.indexOf(socket);
if (index!== -1) {
connectionPool.splice(index, 1);
}
console.log('客户端断开连接,当前连接数:', connectionPool.length);
});
});
server.on('error', (err) => {
throw err;
});
server.listen(8080, () => {
console.log('服务器监听在端口 8080');
});
- 负载均衡:对于高并发场景,可以采用负载均衡策略。例如,使用
cluster
模块来创建多个工作进程,每个进程处理一部分客户端连接。
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`主进程 ${process.pid} 正在运行`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`工作进程 ${worker.process.pid} 已退出`);
});
} else {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
});
server.listen(8080, () => {
console.log(`工作进程 ${process.pid} 监听在端口 8080`);
});
}
- 确保及时响应:
- 非阻塞I/O:Node.js基于事件驱动和非阻塞I/O模型,这使得它在处理多个客户端连接时,不会因为一个连接的I/O操作而阻塞其他连接。例如,在上述示例中,
socket.on('data')
事件处理函数是异步执行的,不会影响其他客户端连接的处理。
- 优化代码:避免在事件处理函数中执行长时间的同步操作。如果有需要,可以将这些操作放在
setImmediate
或process.nextTick
中,将控制权交回事件循环,确保其他客户端请求能及时得到处理。
const net = require('net');
const server = net.createServer((socket) => {
socket.on('data', (data) => {
// 将长时间操作放在setImmediate中
setImmediate(() => {
// 模拟长时间操作
let result = 0;
for (let i = 0; i < 100000000; i++) {
result += i;
}
socket.write('长时间操作结果:'+ result);
});
});
});
server.listen(8080, () => {
console.log('服务器监听在端口 8080');
});