Клиент Websocket не получает никаких сообщений - PullRequest
0 голосов
/ 28 января 2020

У меня есть Python клиент, который открывает веб-сокет-соединение с сервером и подписывается на определенные топи c, используя протокол 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()

Сервер кодов использует для публикации sh сообщение:

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

Когда я проверил значение выше переменных я увидел, что пункт назначения был, как и ожидалось очередь / оповещения . У меня есть java клиент для тестирования, и он прекрасно работает. Я даже попробовал это, подписавшись на /topic/alerts и отправив на него через template.convertAndSend(/topic/alerts), и здесь я тоже ничего не получил. Я рисую полный пробел по этому вопросу и буду признателен за любую помощь!

1 Ответ

0 голосов
/ 04 февраля 2020

После многих дней стрижки волос я наконец выяснил причину и исправление!

  1. Я использовал java клиента, который был WebSocketStompClient stompClient = new WebSocketStompClient(transport);. Метод stompClient.connect(URL, webSocketHttpHeaders, sessionHandler); неявно отправляет штамп CONNECT\n\n\x00\n
  2. Сервер Springboot, настроенный для STOMP, воспринимает это как запрос на подключение и отвечает CONNECT_ACK.
  3. Когда этот ACK отправляется, он также обновляет свой локальный UserRegistry с новым пользователем. Таким образом, внутренний брокер сообщений знает, что есть пользователь, который подписался на то-то и то-то топи c.
  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)
...