关于Nodejs客户端和服务器端 socket 长连接,重启一端后建立连接失败问题

关于Nodejs客户端和服务器端 socket 长连接,重启一端后建立连接失败问题

问题蛮详细的,但看不懂…

3 回复

关于Node.js客户端和服务器端socket长连接,重启一端后建立连接失败问题

问题描述

在使用Node.js开发应用时,经常会遇到需要保持客户端与服务器端长连接的场景。然而,当服务器或客户端的一方重启后,重新建立连接可能会出现问题。

原因分析

  1. 状态未保存:当一方重启后,原有的连接状态信息(如socket对象)会丢失。
  2. 超时问题:网络超时设置可能导致重新连接尝试失败。
  3. 重连机制不完善:没有实现有效的重连逻辑,导致连接无法恢复。

解决方案

为了确保在重启后能够正确地重新建立连接,我们可以实现一个简单的重连机制,并在连接成功后进行必要的状态恢复。

示例代码

服务器端

const net = require('net');

let server = net.createServer((socket) => {
    console.log('Client connected');
    socket.on('end', () => {
        console.log('Client disconnected');
    });
});

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

客户端

const net = require('net');

function createSocket() {
    const socket = new net.Socket();
    
    socket.connect(3000, 'localhost', () => {
        console.log('Connected to server');
    });

    socket.on('error', (err) => {
        console.error(`Socket error: ${err.message}`);
        setTimeout(createSocket, 5000); // 重连机制
    });

    socket.on('close', () => {
        console.log('Disconnected from server');
        setTimeout(createSocket, 5000); // 重连机制
    });
}

createSocket();

解释

  1. 服务器端:创建一个简单的TCP服务器,监听3000端口。
  2. 客户端
    • createSocket函数负责创建一个新的socket连接。
    • socket.connect用于尝试连接到服务器。
    • socket.on('error')处理连接错误,并在发生错误时重新尝试连接。
    • socket.on('close')处理断开连接的情况,同样在断开连接时重新尝试连接。
    • setTimeout(createSocket, 5000)表示在5秒后重新尝试连接。

通过上述方法,可以确保即使服务器或客户端重启,也能自动恢复连接。


这不是因为没重启那端的pool中的TCP连接都已经失效了吗?你得有个心跳+重连的机制吧。

回答

在Node.js中,使用socket进行长连接时,如果客户端或服务器端重启,可能会导致重新建立连接失败。这是因为连接中断后,两端需要正确地处理重连逻辑。

示例代码

以下是一个简单的示例,展示如何实现客户端和服务端的长连接,并处理重启后的重新连接。

服务端代码 (server.js)

const net = require('net');

let server;
function startServer() {
    server = net.createServer((socket) => {
        console.log("Client connected");
        socket.on('end', () => {
            console.log("Client disconnected");
            socket.destroy(); // 可选,销毁旧连接
        });
        socket.on('error', (err) => {
            console.error(err);
        });
    });

    server.listen(3000, () => {
        console.log('Server is listening on port 3000');
    });
}

// 启动服务器
startServer();

// 模拟重启服务器
setTimeout(() => {
    server.close(() => {
        console.log("Server restarted");
        startServer();
    });
}, 10000);

客户端代码 (client.js)

const net = require('net');

function startClient() {
    const client = new net.Socket();
    
    client.connect(3000, 'localhost', () => {
        console.log("Connected to server");
    });

    client.on('data', (data) => {
        console.log(`Received: ${data}`);
    });

    client.on('close', () => {
        console.log("Disconnected from server");
        setTimeout(() => {
            startClient(); // 自动重新连接
        }, 1000);
    });

    client.on('error', (err) => {
        console.error(err);
        setTimeout(() => {
            startClient(); // 自动重新连接
        }, 1000);
    });
}

// 启动客户端
startClient();

// 模拟重启客户端
setTimeout(() => {
    process.exit(0); // 退出当前进程模拟重启
}, 10000);

解释

  • 服务端 (server.js):创建一个TCP服务器并监听端口3000。每当客户端连接时,打印一条消息。当客户端断开连接时,处理end事件,并可以选择性地销毁旧连接。模拟服务器重启,关闭现有服务器实例并重新启动新的服务器。

  • 客户端 (client.js):尝试连接到服务器。连接成功后,监听数据接收事件。当客户端断开连接或遇到错误时,通过定时器自动重新连接。

这样可以确保即使在重启之后,客户端和服务端也能自动恢复连接。

回到顶部