You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js WS包技术疑问:send回调执行顺序及连接关闭延迟问题

Node.js WebSocket服务器与Python客户端的问题解答

服务器代码(Node.js)

const WebSocket = require('ws');

function startSocket() {
    let socket = new WebSocket.Server({ port: 80 });
    console.log('Websocket started...')

    socket.on('connection', function(connection) {
        console.log('[open] JS: Connection open')
        connection.send('You have open a connection',(error, number=5555)=>{console.log(number)})
        console.log('JS: Closing the connection...')
        socket.close()
    })

    socket.on('close', function(event) {
        console.log('JS: Connection closed')
    })
}

客户端代码(Python)

import websockets
import asyncio

async def connectSocket():
    async with websockets.connect('ws://localhost:80/') as ws:
        ipt = input()
        await ws.send(ipt)
        msg = await ws.recv()
        print(msg)

asyncio.run(connectSocket())

服务器输出

客户端连接后:

Websocket started...

[open] JS: Connection open

JS: Closing the connection...

5555

客户端发送消息后:

JS: Connection closed


问题1:为何send()回调中的5555没有在“JS: Closing the connection...”之前打印?

因为connection.send()是异步操作:调用send时只是把消息加入发送队列,不会等消息实际发送完成就继续执行后续同步代码。console.log('JS: Closing the connection...')是同步执行的,会立刻输出;而send的回调要等消息成功发送到客户端、底层IO操作完成后才会触发,所以5555会在“Closing...”之后打印。

问题2:明明在打印“JS: Closing the connection...”后立即调用了socket.close(),为何socket的close事件回调要等到客户端发送消息后才触发?

你调用的socket.close()是关闭WebSocket服务器实例,不是关闭当前的客户端连接。ws库的Server.close()是优雅关闭逻辑:

  1. 先停止监听新的客户端连接请求;
  2. 不会主动关闭已建立的客户端连接;
  3. 只有当所有已建立的客户端连接都断开后,才会触发Server的close事件。

你的代码里,客户端连接后,服务器没有主动关闭这个客户端连接(要关闭单个连接得调用connection.close()),所以连接一直处于活跃状态。直到客户端发送消息后,后续流程中连接因服务器已停止服务而断开,此时所有活跃连接都关闭,Server的close事件才会触发,打印“JS: Connection closed”。


内容的提问来源于stack exchange,提问作者Hiperfly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:20:50