基本思路
- 客户端:
- 定期向服务器发送心跳包,告知服务器自己处于活跃状态。
- 启动定时器,按照固定时间间隔发送心跳消息。
- 处理服务器返回的心跳响应,若长时间未收到响应,可认为连接异常。
- 服务器:
- 接收客户端发送的心跳包,并记录客户端的活跃状态。
- 为每个客户端设置一个心跳超时时间,若在该时间内未收到客户端的心跳包,则判定客户端离线。
TCP协议代码示例
服务端代码(server.js)
const net = require('net');
const clients = new Map();
const HEARTBEAT_TIMEOUT = 5000; // 心跳超时时间5秒
const server = net.createServer((socket) => {
socket.id = Date.now();
clients.set(socket.id, socket);
socket.on('data', (data) => {
const message = data.toString().trim();
if (message === 'heartbeat') {
socket.heartbeatReceived = Date.now();
socket.write('heartbeat response\n');
}
});
socket.on('end', () => {
clients.delete(socket.id);
});
});
server.listen(8080, () => {
console.log('Server listening on port 8080');
});
setInterval(() => {
const now = Date.now();
clients.forEach((socket, id) => {
if (!socket.heartbeatReceived || now - socket.heartbeatReceived > HEARTBEAT_TIMEOUT) {
console.log(`Client ${id} timeout, closing connection`);
socket.end();
clients.delete(id);
}
});
}, HEARTBEAT_TIMEOUT);
客户端代码(client.js)
const net = require('net');
const HEARTBEAT_INTERVAL = 3000; // 心跳发送间隔3秒
const client = net.connect({ port: 8080 }, () => {
console.log('Connected to server');
setInterval(() => {
client.write('heartbeat\n');
}, HEARTBEAT_INTERVAL);
});
client.on('data', (data) => {
const message = data.toString().trim();
if (message === 'heartbeat response') {
console.log('Received heartbeat response from server');
}
});
client.on('end', () => {
console.log('Connection closed by server');
});
HTTP协议代码示例
服务端代码(server.js)
const http = require('http');
const express = require('express');
const app = express();
const clients = new Map();
const HEARTBEAT_TIMEOUT = 5000; // 心跳超时时间5秒
app.get('/heartbeat', (req, res) => {
const clientIp = req.ip;
clients.set(clientIp, Date.now());
res.send('heartbeat response');
});
const server = http.createServer(app);
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
setInterval(() => {
const now = Date.now();
clients.forEach((lastHeartbeat, clientIp) => {
if (now - lastHeartbeat > HEARTBEAT_TIMEOUT) {
console.log(`Client ${clientIp} timeout`);
clients.delete(clientIp);
}
});
}, HEARTBEAT_TIMEOUT);
客户端代码(client.js)
const axios = require('axios');
const HEARTBEAT_INTERVAL = 3000; // 心跳发送间隔3秒
setInterval(() => {
axios.get('http://localhost:3000/heartbeat')
.then(response => {
console.log('Received heartbeat response from server');
})
.catch(error => {
console.error('Error sending heartbeat:', error);
});
}, HEARTBEAT_INTERVAL);