SockJS Python Client

六月ゝ 毕业季﹏ 提交于 2020-01-01 08:52:07

问题


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

We are creating a command line interface based in Python and we would like to add some of the functionality which is already available using websockets.

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

PS_ I am aware of a simple library which I did not tested but it does not have the capability to subscribe to a topic

PS2_ As I can connect directly to a STOMP at RabbitMQ from python and subscribe to a topic but exposing RabbitMQ directly does not feel right. Any comments around for second option ?


回答1:


The solution I used was to not use the SockJS protocol and instead do "plain ol' web sockets" and used the websockets package in Python and sending Stomp messages over it using the stomper package. The stomper package just generates strings that are "messages" and you just send those messages over websockets using ws.send(message)

Spring Websockets config on the 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 Python client side of 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 Stomp formatted message, which has a pretty simple format. MSG is a quick and dirty class 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 isn't the most complete solution. There isn't an unsubscribe and the id for the Stomp subscription is randomly generated and not "remembered." But, the stomper library provides you the ability to create unsubscribe messages.

Anything on the server side that is sent to /something-to-subscribe-to will be received by all the 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");
        }
    }

}


来源:https://stackoverflow.com/questions/34574349/sockjs-python-client

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!