3

I have Python client which opens a websocket connection to a server and subscribes to particular topic using STOMP protocol, subscription goes just fine as i see on the server all is fine. However, When the server publishes a few messages the client does not receive any. Here are the codes used:

Client

# 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 uses to publish the message:

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

When i checked out the value of the above variables i saw that destination was as expected queue/alerts. I have java client to test out as well and it works just fine. I have even tried this by subscribing to /topic/alerts and sending to it via template.convertAndSend(/topic/alerts), here too i received nothing. I am a drawing a complete blank on this and would appreciate any sort of help!

srinivas kumar
  • 373
  • 2
  • 8
  • I tried the same steps as https://stackoverflow.com/questions/34574349/sockjs-python-client yet it does not work, could someone please help out here? – srinivas kumar Jan 29 '20 at 09:47

1 Answers1

8

After many days of hair pulling I finally figured out the reason and the fix!

  1. The java client I used was WebSocketStompClient stompClient = new WebSocketStompClient(transport);.The stompClient.connect(URL, webSocketHttpHeaders, sessionHandler); method implicitly sends a stomp CONNECT\n\n\x00\n
  2. The Springboot server which has been configured for STOMP understands this as a connection request and responds with a CONNECT_ACK.
  3. When this ACK is sent it also updates it's local UserRegistry with the new user. So the internal message broker knows that there is a user who has subscribed to so-and-so topic.
  4. In my Python code, i had merely opened a Websocket connection and after that directly sent a SUBSCRIBE message. So the broker never got a CONNECT so the user was never stored! This resulted in the messages later on being published to be merely discarded by the broker.
  5. The fix was to send a CONNECT\n\n\x00\n after opening up the connection and before the subscription. Here is the code:
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)
srinivas kumar
  • 373
  • 2
  • 8
  • I kind of suspected this was the issue on my end because although I was getting a connection it wasn't "registering" as a STOMP client – Jeef Jun 05 '20 at 10:35
  • Sorry but what do you mean in point 1 with method implicitly sends a stomp CONNECT\n\n\x00\n? How can I set it? Or can you show your Spring Boot Code too? – CptDayDreamer Nov 24 '20 at 03:20
  • No it cannot be set, once you call the method `stompClient.connect(URL, webSocketHttpHeaders, sessionHandler); ` this method after establishing websocket connection sends the CONNECT message next. Note that this in the Stomp Java client. Also this needs to be sent so that springboot server can update it's registry with this client and send back CONNECT_ACK. – srinivas kumar Nov 29 '20 at 14:09
  • @srinivaskumar okay but I'm using Spring as client and Python as server but I can't send the right message to get the stompClient of Spring Boot connected. It will never go in the afterConnected() method or anything. – CptDayDreamer Dec 04 '20 at 13:25
  • Perhaps, you could share your code, I can have a look. @CptDayDreamer – srinivas kumar Dec 09 '20 at 16:02
  • Please lookup my unsolved question @srinivaskumar https://stackoverflow.com/questions/64886685/django-channels-with-spring-boot-websockets-stompsession-do-not-work – CptDayDreamer Dec 11 '20 at 01:27