Nodejs 当客户端连接断开后,socket服务器端 怎么能终止业务计算

Nodejs 当客户端连接断开后,socket服务器端 怎么能终止业务计算

用nodejs 实现了一个socket server,有一个问题,就是与客户端的一个连接,客户端发送请求,服务器端处理业务,但是实际这个connection断开后,怎么能够让服务器马上也终止这个业务处理,不用返回给客户端数据了,

4 回复

Node.js 当客户端连接断开后,Socket 服务器端如何终止业务计算

在使用 Node.js 实现 Socket 服务器时,可能会遇到这样一个问题:客户端与服务器之间的连接断开后,服务器端仍在进行某些业务计算。为了确保服务器能够及时终止这些不必要的计算,可以通过监听 closeend 事件来实现。

示例代码

以下是一个简单的示例,展示了如何通过监听 close 事件来终止业务计算:

const net = require('net');

const server = net.createServer((socket) => {
    console.log('Client connected');

    // 处理客户端的请求
    socket.on('data', (data) => {
        console.log('Received data:', data.toString());

        // 模拟一个耗时的业务计算
        setTimeout(() => {
            console.log('Business logic completed');
            socket.write('Response from server');
            socket.end();
        }, 5000); // 假设这是耗时5秒的业务逻辑
    });

    // 监听连接关闭事件
    socket.on('close', () => {
        console.log('Connection closed, terminating business logic');
        // 如果业务逻辑仍在运行,可以在这里添加终止逻辑
        clearTimeout(timeoutId);
    });

    // 监听错误事件
    socket.on('error', (err) => {
        console.error('Socket error:', err);
        // 如果发生错误,也可以在此处终止业务逻辑
        clearTimeout(timeoutId);
    });
});

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

解释

  1. 创建服务器

    • 使用 net.createServer() 创建一个 TCP 服务器。
    • 在连接成功时,打印一条消息,并设置处理客户端数据的回调函数。
  2. 处理客户端数据

    • 监听 data 事件以处理客户端发送的数据。
    • 使用 setTimeout 模拟一个耗时的业务逻辑。
  3. 监听连接关闭事件

    • 使用 socket.on('close', callback) 监听连接关闭事件。
    • 在连接关闭时,可以清除定时器(即终止业务逻辑)。
  4. 监听错误事件

    • 使用 socket.on('error', callback) 监听可能发生的错误。
    • 在发生错误时,同样可以清除定时器以终止业务逻辑。

通过这种方式,当客户端断开连接时,服务器端可以及时终止正在进行的业务计算,避免资源浪费。


服务器,通过心跳知道客户端断开,然后 发送一个事件给 到,处理业务请求的逻辑里面,业务请求的逻辑里面,监听这个断开事件,接收到事件后,终止计算

如果是socket.io, 检测到断开连接,不知道会不会自动触发disconnect事件。如果是,那么就好解决了。

当你在Node.js中实现一个Socket服务器时,如果客户端断开了连接,你可能希望立即终止服务器上的业务处理。可以通过监听'close'事件来检测连接是否已经关闭,并在这种情况下取消正在进行的业务计算。

这里提供一种简单的实现方式:

  1. 使用EventEmitter管理任务
    • 在处理业务时,你可以将业务封装在一个任务中,并将其与当前连接关联起来。
    • 当连接断开时,从任务队列中移除该任务,并停止其执行。
const net = require('net');
const EventEmitter = require('events');

class SocketServer extends EventEmitter {
    constructor(port) {
        super();
        this.server = net.createServer(this.handleConnection.bind(this));
        this.server.listen(port, () => console.log(`Server listening on port ${port}`));
        this.tasks = new Map();
    }

    handleConnection(socket) {
        const clientId = socket.remoteAddress + ':' + socket.remotePort;
        
        socket.on('end', () => {
            console.log(`Client ${clientId} disconnected`);
            this.tasks.delete(clientId);
        });

        socket.on('data', (data) => {
            console.log(`Received data from client ${clientId}: ${data.toString()}`);
            const taskId = this.runTask(data, socket);

            this.tasks.set(clientId, taskId);
        });
    }

    runTask(data, socket) {
        return setTimeout(() => {
            if (!this.tasks.has(socket.remoteAddress + ':' + socket.remotePort)) {
                console.log('Task cancelled due to connection closure.');
                return;
            }
            // Simulate business logic
            console.log(`Processing data: ${data.toString()}`);
        }, 10000); // 假设这是一个耗时任务
    }
}

const server = new SocketServer(3000);

在这个例子中:

  • handleConnection方法处理新的连接,并监听'end'事件,当连接断开时删除任务。
  • runTask方法模拟一个耗时的任务。如果连接已经断开(即tasks中没有该任务),则任务会被取消。

这种方法可以确保当客户端断开连接时,服务器能够立即取消相关的长时间运行的任务。

回到顶部