关键实现步骤
- 创建 TCP 服务器:
使用
net
模块的 net.createServer()
方法创建一个 TCP 服务器实例。在回调函数中,处理客户端连接,为每个连接分配唯一标识,方便后续管理。
const net = require('net');
const server = net.createServer((socket) => {
// 处理新连接
});
server.listen(8080, () => {
console.log('TCP server listening on port 8080');
});
- 客户端连接:
客户端使用
net.connect()
方法连接到服务器,在连接成功后可以进行消息的发送与接收。
const net = require('net');
const socket = net.connect({ port: 8080 }, () => {
console.log('Connected to server');
});
- 连接管理:
- 维护连接列表:在服务器端,创建一个数据结构(如数组或对象)来存储所有当前连接的客户端套接字。这样可以方便地向所有或特定客户端发送消息。
- 处理连接断开:监听
'close'
事件,当客户端断开连接时,从连接列表中移除该客户端套接字,释放相关资源。
server.on('connection', (socket) => {
// 将新连接的 socket 添加到连接列表
const connections = [];
connections.push(socket);
socket.on('close', () => {
const index = connections.indexOf(socket);
if (index!== -1) {
connections.splice(index, 1);
}
});
});
- 消息发送与接收:
- 消息接收:在服务器端和客户端,监听
'data'
事件来接收消息。接收到的消息可能是字节流形式,需要根据协议进行解析,例如解析为 JSON 格式。
socket.on('data', (data) => {
const message = JSON.parse(data.toString());
console.log('Received message:', message);
});
- 消息发送:服务器端可以遍历连接列表,向指定或所有客户端发送消息。客户端根据业务需求,调用
socket.write()
方法发送消息。
// 服务器端向所有客户端发送消息
connections.forEach((clientSocket) => {
const message = { type: 'broadcast', content: 'Hello, everyone!' };
clientSocket.write(JSON.stringify(message));
});
// 客户端发送消息
const message = { type: 'chat', content: 'Hello, server!' };
socket.write(JSON.stringify(message));
技术要点
- 消息协议设计:
定义清晰的消息协议,包括消息类型(如聊天消息、系统通知等)、数据格式(如 JSON)等,以便服务器和客户端能够正确解析和处理消息。
- 流量控制:
由于是长连接,可能会出现数据发送过快导致缓冲区溢出的情况。可以使用
socket.setWriteBufferSize()
方法设置缓冲区大小,并通过监听 'drain'
事件来判断缓冲区是否有足够空间继续写入数据。
- 错误处理:
在连接建立、消息发送和接收过程中,可能会出现各种错误,如连接超时、网络故障等。需要在服务器端和客户端都做好全面的错误处理,例如监听
'error'
事件,及时关闭连接并进行相应提示。
- 安全性:
- 数据加密:对于敏感消息,如用户聊天内容,使用加密算法(如 TLS/SSL)对数据进行加密传输,防止数据被窃取或篡改。
- 身份验证:在连接建立初期,对客户端进行身份验证,确保只有合法客户端能够连接并进行消息交互。可以使用用户名密码、令牌等方式实现。