python - Websocket客户端未收到任何消息
问题描述
我有 Python 客户端,它打开到服务器的 websocket 连接并使用 STOMP 协议订阅特定主题,订阅一切正常,因为我在服务器上看到一切都很好。但是,当服务器发布一些消息时,客户端不会收到任何消息。以下是使用的代码:
客户
# coding: utf-8
import websocket
import stomp
import stomper
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInByaW5jaXBhbF9uYW1lIjoiYWRtaW4iLCJpc3MiOiJBdGhlbmEiLCJ1c2VydHlwZSI6IkxPQ0FMIiwiYW9zX3ZlcnNpb24iOiJldXBocmF0ZXMtNS4xMS1zdGFibGUiLCJyZWdpb24iOiJlbi1VUyIsImV4cCI6MTczNDI4MDI3NywidXVpZCI6ImI4MzhjOGRkLWI4NmQtNGNkZS05ZTE4LTUxM2E1OTk4ODhhYyIsImlhdCI6MTU3NjYwMDI3NywiYXV0aG9yaXRpZXMiOiJST0xFX0NMVVNURVJfQURNSU4sUk9MRV9NVUxUSUNMVVNURVJfQURNSU4sUk9MRV9VU0VSX0FETUlOLFJPTEVfQ0xVU1RFUl9WSUVXRVIiLCJqdGkiOiI1NTU1ZjEwZC04NGQ5LTRkZGYtOThhNC1mZmI1OTM1ZTQwZWEifQ.LOMX6ppkcSBBS_UwW9Qo2ieWZAGrKqADQL6ZQuTi2oieYa_LzykNiGMWMYXY-uw40bixDcE-aVWyrIEZQbVsvA"
headers = {"Authorization": "Bearer " + token}
uri = "ws://127.0.0.1:8765/notifications/websocket"
def on_msg(ws, msg):
print(msg)
def on_error(ws, err):
print(err)
def on_closed(ws):
print("#Closed#")
def on_open(ws):
sub = stomper.subscribe("/user/queue/alert", "MyuniqueId", ack="auto")
ws.send(sub)
headers = {"Authorization": "Bearer " + token}
websocket.enableTrace(True)
ws = websocket.WebSocketApp(uri, header=headers, on_message=on_msg, on_error=on_error, on_close=on_closed)
ws.on_open = on_open
ws.run_forever()
代码服务器用于发布消息:
for (WatchesSubscription s : subscriptions) {
template.convertAndSendToUser(s.getSession().getUser(), destination, dto);
}
当我检查上述变量的值时,我看到目的地是预期的queue/alerts。我也有 java 客户端来测试,它工作得很好。我什至通过订阅/topic/alerts
并发送给它来尝试这个template.convertAndSend(/topic/alerts)
,在这里我也没有收到任何东西。我对此一无所知,希望能提供任何帮助!
解决方案
经过几天的拉头发,我终于弄清楚了原因和解决方法!
- 我使用的java客户端是
WebSocketStompClient stompClient = new WebSocketStompClient(transport);
。该stompClient.connect(URL, webSocketHttpHeaders, sessionHandler);
方法隐式发送一个stompCONNECT\n\n\x00\n
- 为 STOMP 配置的 Springboot 服务器将此理解为连接请求,并以
CONNECT_ACK
. - 当这个 ACK 被发送时,它也会
UserRegistry
用新用户更新它的本地信息。所以内部消息代理知道有一个用户订阅了某某主题。 - 在我的 Python 代码中,我只是打开了一个 Websocket 连接,然后直接发送了一条
SUBSCRIBE
消息。所以经纪人从来没有得到一个CONNECT
所以用户从来没有被存储!这导致稍后发布的消息仅被代理丢弃。 CONNECT\n\n\x00\n
解决方法是在打开连接之后和订阅之前发送一个。这是代码:
def on_open(ws):
#The magic happens here!
ws.send("CONNECT\naccept-version:1.0,1.1,2.0\n\n\x00\n")
sub = stomper.subscribe("/user/queue/alert", "MyuniqueId", ack="auto")
ws.send(sub)
推荐阅读
- c - 使用 pmap 分析进程的内存映射。[堆]
- python - 如何将 subprocess.run 的输出保存到字符串中?
- mysql - SQL(?)如何从面包屑解析父类别以更新具有 parentID 的字段?
- oracle - 如何使用 SQL Developer 管理带有回滚的单元测试
- node.js - 通过模拟器连接时 Botkit 未经授权(Microsoft Bot Framework)
- java - 即使没有发生异常,@Retryable 也会多次调用
- c# - 使用 Visual Studio 2017 编译的 .exe 的 Windows 资源管理器文件属性“详细信息”选项卡中的文件版本 0.0.0.0
- sql-server - 如何使用 OPENQUERY 正确执行更新链接服务器表的存储过程?
- node.js - 从 Firebase 可调用函数获取用户 IP 地址
- excel - 使用 VBA 从 excel 复制/粘贴到 IE 网页时如何使提交按钮出现?