Python SockJS Client

I have a website (Java + Spring) that relies on Websockets ( Stomp over Websockets for Spring + RabbitMQ + SockJS) for some functions.

We are creating a Python-based command line interface, and we would like to add some of the functionality that is already available with websockets.

Does anyone know how to use the python client so that I can connect using the SockJS protocol?

PS_ I know a simple library that I have not tested, but it does not have the ability to subscribe to a topic

PS2_ How can I directly connect to STOMP in RabbitMQ from python and subscribe to a topic, but exposing RabbitMQ directly does not seem right. Any comments around the second option?

+10
source share
1 answer

The solution I used was to not use the SockJS protocol, but instead to do โ€œregular web socketsโ€, use the websockets package in Python and send Stomp messages through it using the stomper package. The stomper package simply generates strings that are "messages" and you simply send these messages via web sockets using ws.send(message)

Spring Websockets configuration on server:

 @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/my-ws-app"); // Note we aren't doing .withSockJS() here } } 

And on the client side of the Python code:

 import stomper from websocket import create_connection ws = create_connection("ws://theservername/my-ws-app") v = str(random.randint(0, 1000)) sub = stomper.subscribe("/something-to-subscribe-to", v, ack='auto') ws.send(sub) while not True: d = ws.recv() m = MSG(d) 

Now d will be a message in Stomp format, which has a fairly simple format. MSG is a quick and dirty class that I wrote to parse it.

 class MSG(object): def __init__(self, msg): self.msg = msg sp = self.msg.split("\n") self.destination = sp[1].split(":")[1] self.content = sp[2].split(":")[1] self.subs = sp[3].split(":")[1] self.id = sp[4].split(":")[1] self.len = sp[5].split(":")[1] # sp[6] is just a \n self.message = ''.join(sp[7:])[0:-1] # take the last part of the message minus the last character which is \00 

This is not the most complete solution. There is no unsubscription, and the identifier for the Stomp subscription is randomly generated, not "remembered." But the stomper library gives you the ability to create unsubscribe messages.

Everything on the server side sent to /something-to-subscribe-to will be received by all Python clients subscribed to it.

 @Controller public class SomeController { @Autowired private SimpMessagingTemplate template; @Scheduled(fixedDelayString = "1000") public void blastToClientsHostReport(){ template.convertAndSend("/something-to-subscribe-to", "hello world"); } } } 
+3
source

Source: https://habr.com/ru/post/1239707/


All Articles