【发布时间】:2021-08-04 13:12:28
【问题描述】:
我有以下应该运行 websockets 服务器 + NATS 服务器的 sn-p 代码。
每次有新消息到达 NATS,websocket 服务器应该将消息发送到所有连接的 websocket。我看到一个奇怪的行为,因为 websocket 连接没有保持活动状态。
我想我在 asyncio 循环中搞混了。知道我在这里缺少什么吗?
import asyncio
import os
import logging
import json
import websockets
from nats.aio.client import Client as NATS
async def main():
#
# websocket related stuff
#
clients = set()
# Register each new client
async def register(websocket, path):
clients.add(websocket)
await websockets.serve(register, "localhost", 8765)
# NATS related stuff
# Send message to all connected websockets
async def message_handler(msg):
data = msg.data.decode()
logging.debug('handling new message: {}'.format(data))
for ws in clients:
await ws.send("test")
# Connection to NATS message queue
nats_url = os.getenv('NATS_URL', 'nats://nats:4222')
nc = NATS()
await nc.connect([nats_url])
# Subscription to all data related messages
await nc.subscribe("data.*", cb=message_handler)
await asyncio.Event().wait()
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
asyncio.run(main())
每次有新的websocket客户端连接,注册后连接关闭:
DEBUG:websockets.protocol:server - state = CONNECTING
DEBUG:websockets.protocol:server - event = connection_made(<_SelectorSocketTransport fd=6 read=idle write=<idle, bufsize=0>>)
DEBUG:websockets.protocol:server - event = data_received(<535 bytes>)
DEBUG:websockets.server:server < GET /?token=234RZRZER HTTP/1.1
DEBUG:websockets.server:server < Headers([('Host', '127.0.0.1:8765'), ('Connection', 'Upgrade'), ('Pragma', 'no-cache'), ('Cache-Control', 'no-cache'), ('Upgrade', 'websocket'), ('Origin', 'file://'), ('Sec-WebSocket-Version', '13'), ('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36'), ('Accept-Encoding', 'gzip, deflate, br'), ('Accept-Language', 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7'), ('Sec-GPC', '1'), ('Sec-WebSocket-Key', 'KL0hFYOjOc25n/XwcON/9A=='), ('Sec-WebSocket-Extensions', 'permessage-deflate; client_max_window_bits')])
DEBUG:websockets.server:server > HTTP/1.1 101 Switching Protocols
DEBUG:websockets.server:server > Headers([('Upgrade', 'websocket'), ('Connection', 'Upgrade'), ('Sec-WebSocket-Accept', 'JpQAUwE+IzhPyNdqQuLeyROFhGo='), ('Sec-WebSocket-Extensions', 'permessage-deflate'), ('Date', 'Wed, 04 Aug 2021 13:21:40 GMT'), ('Server', 'Python/3.8 websockets/9.1')])
DEBUG:websockets.protocol:server - state = OPEN
DEBUG:websockets.protocol:server - state = CLOSING
DEBUG:websockets.protocol:server > Frame(fin=True, opcode=<Opcode.CLOSE: 8>, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:server - event = data_received(<8 bytes>)
DEBUG:websockets.protocol:server < Frame(fin=True, opcode=<Opcode.CLOSE: 8>, data=b'\x03\xe8', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:server x half-closing TCP connection
DEBUG:websockets.protocol:server - event = eof_received()
DEBUG:websockets.protocol:server - event = connection_lost(None)
DEBUG:websockets.protocol:server - state = CLOSED
DEBUG:websockets.protocol:server x code = 1000, reason = [no reason]
【问题讨论】:
-
我会将两个关注点(监听 NATS,处理 websocket)分成两个任务,并可能使用 asyncio.Queue() 在它们之间推送消息......这可能会使整个事情变得清晰.最后的无限等待也不应该是必要的。
-
也就是说,“websocket 连接不保持活动状态”是什么意思?
-
@AKX 抱歉,我已经添加了我得到的连接/断开连接日志
-
啊,有道理:) 你的 WS 连接处理程序不是无限异步循环,所以连接会立即被 websockets 库关闭。
-
哼...即使整个 main() 在循环中被调用?我很确定我在那个设置中做错了什么:)
标签: python websocket python-asyncio nats.io