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()是优雅关闭逻辑:
- 先停止监听新的客户端连接请求;
- 不会主动关闭已建立的客户端连接;
- 只有当所有已建立的客户端连接都断开后,才会触发Server的
close事件。
你的代码里,客户端连接后,服务器没有主动关闭这个客户端连接(要关闭单个连接得调用connection.close()),所以连接一直处于活跃状态。直到客户端发送消息后,后续流程中连接因服务器已停止服务而断开,此时所有活跃连接都关闭,Server的close事件才会触发,打印“JS: Connection closed”。
内容的提问来源于stack exchange,提问作者Hiperfly
相关产品推荐
相关产品推荐

