Websocket客户端未接收到任何消息。

3

我是一名中文翻译助手,以下是涉及IT技术的翻译内容。需要翻译的内容为:我有一个Python客户端,它通过STOMP协议打开websocket连接并订阅特定主题,订阅正常,我已经在服务器上验证过。然而,当服务器发布一些消息时,客户端没有收到任何消息。下面是使用的代码:

客户端:

# 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()

Code server用于发布消息的代码:

    for (WatchesSubscription s : subscriptions) {
            template.convertAndSendToUser(s.getSession().getUser(), destination, dto);
        }

当我检查上述变量的值时,我发现目标是预期中的queue/alerts。我也有一个Java客户端进行测试,它可以正常工作。我甚至尝试通过订阅/topic/alerts并通过template.convertAndSend(/topic/alerts)发送到它,但这里我仍然没有收到任何消息。我对此完全一无所知,希望能得到任何形式的帮助!


我尝试了与https://dev59.com/0VsW5IYBdhLWcg3wyZww相同的步骤,但它不起作用,有人可以帮忙吗? - srinivas kumar
1个回答

8

在经历了多天的折磨后,我终于找到了问题和解决方法!

  1. 我使用的Java客户端是WebSocketStompClient stompClient = new WebSocketStompClient(transport);stompClient.connect(URL, webSocketHttpHeaders, sessionHandler); 方法会隐式发送一个stomp的CONNECT\n\n\x00\n
  2. 已配置为STOMP的Springboot服务器将此视为连接请求,并响应CONNECT_ACK
  3. 当发送ACK时,它还会使用新用户更新其本地的UserRegistry。 因此,内部消息代理知道有一个用户订阅了某个主题。
  4. 在我的Python代码中,我仅仅打开了一个websocket连接,然后直接发送了一个SUBSCRIBE消息。 所以代理没有收到CONNECT,所以用户也没有被存储! 这导致后来发布的消息被代理简单地丢弃。
  5. 解决方法是在打开连接并订阅之前发送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)

我有点怀疑这是我的问题,因为虽然我能够建立连接,但它并没有被"注册"为一个STOMP客户端。 - Jeef
抱歉,但是在第一点中你说的“方法隐式发送了一个stomp CONNECT\n\n\x00\n”是什么意思?我该如何设置它?或者你能展示一下你的Spring Boot代码吗? - CptDayDreamer
不,它不能被设置。一旦调用方法stompClient.connect(URL, webSocketHttpHeaders, sessionHandler);,该方法在建立WebSocket连接后会发送CONNECT消息。请注意,这是在Stomp Java客户端中。同时,需要发送此消息以便springboot服务器可以更新其注册表,并返回CONNECT_ACK。 - srinivas kumar
@srinivaskumar 好的,但我正在使用Spring作为客户端,Python作为服务器,但我无法发送正确的消息以使Spring Boot的stompClient连接。它永远不会进入afterConnected()方法或其他任何方法。 - CptDayDreamer
或许你可以分享一下你的代码,我可以看看。@CptDayDreamer - srinivas kumar
请在@srinivaskumar的stackoverflow页面上查看我的未解决问题:https://stackoverflow.com/questions/64886685/django-channels-with-spring-boot-websockets-stompsession-do-not-work - CptDayDreamer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接