面试题答案
一键面试检测连接是否稳定
-
心跳机制
- 定期(例如每隔一定时间间隔,如1 - 5秒)向对方发送一个简单的心跳包(可以是一个特定格式的消息,如
{type: 'heartbeat'}
)。 - 在接收端,当收到心跳包时,回复一个确认消息(如
{type: 'heartbeat - ack'}
)。 - 如果发送端在一定时间内(如心跳间隔的2 - 3倍时间)没有收到确认消息,则认为连接可能不稳定。
- 定期(例如每隔一定时间间隔,如1 - 5秒)向对方发送一个简单的心跳包(可以是一个特定格式的消息,如
-
监测数据传输时间
- 在发送数据时记录发送时间戳,在接收端收到数据后,将数据连同接收时间戳一起返回。
- 发送端收到返回数据后,计算数据往返时间(RTT)。如果RTT超过某个设定的阈值(例如根据历史数据或经验设定为100ms - 1s),则可能表示连接不稳定。
-
检测丢包
- 为每个发送的数据包添加一个序列号。
- 接收端按照序列号顺序接收数据,如果检测到序列号不连续,且缺失的序列号在一定范围内(例如连续缺失3个以内),则认为可能发生了丢包,通知发送端。
连接不稳定时的重连操作
- 立即重连
- 当检测到连接不稳定(如心跳超时、RTT超阈值或确认丢包)时,立即尝试重新建立连接。使用
net
模块(假设是TCP连接)的createConnection
方法(对于UDP连接,可以重新初始化dgram
套接字)。 - 例如,对于TCP连接:
- 当检测到连接不稳定(如心跳超时、RTT超阈值或确认丢包)时,立即尝试重新建立连接。使用
const net = require('net');
const client = new net.Socket();
function reconnect() {
client.connect({port: 8080, host: '127.0.0.1'}, () => {
console.log('Re - connected');
});
client.on('error', (err) => {
console.error('Re - connect error:', err);
setTimeout(reconnect, 1000);
});
}
- 指数退避重连
- 每次重连失败后,增加重连的时间间隔。例如,第一次重连间隔1秒,第二次2秒,第三次4秒,以此类推。
- 代码示例:
const net = require('net');
const client = new net.Socket();
let reconnectInterval = 1000;
function reconnect() {
client.connect({port: 8080, host: '127.0.0.1'}, () => {
console.log('Re - connected');
reconnectInterval = 1000;
});
client.on('error', (err) => {
console.error('Re - connect error:', err);
setTimeout(reconnect, reconnectInterval);
reconnectInterval *= 2;
});
}
数据缓存与补发
- 数据缓存
- 使用一个数组或队列来缓存需要发送的数据。例如,对于需要发送的数据
data
:
- 使用一个数组或队列来缓存需要发送的数据。例如,对于需要发送的数据
const dataQueue = [];
function sendData(data) {
dataQueue.push(data);
if (!client.writable) {
return;
}
sendQueuedData();
}
- 补发
- 当连接重新建立成功后,遍历缓存的数据队列,依次重新发送数据。
- 例如:
function sendQueuedData() {
while (dataQueue.length > 0 && client.writable) {
const data = dataQueue.shift();
client.write(data);
}
}
client.on('connect', () => {
sendQueuedData();
});