SockJS Python 客户端

问题描述

我有一个依赖 Websockets 的网站 (Java + Spring) (Stomp over Websockets for Spring + RabbitMQ + SockJS) 用于某些功能.

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

我们正在创建一个基于 Python 的命令行界面,我们希望添加一些使用 websockets 已经可用的功能.

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.

有谁知道如何使用 python 客户端以便我可以使用 SockJS 协议进行连接?

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

PS_ 我知道一个 简单库 我没有测试但它没有订阅主题的能力

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_ 因为我可以直接连接到 STOMP at RabbitMQ from python 并订阅一个主题但是直接暴露 RabbitMQ 感觉不对.关于第二个选项的任何评论?

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 ?


解决方案

我使用的解决方案是不使用 SockJS 协议,而是使用plain ol' web sockets"并使用 Python 中的 websockets 包并通过 Stomp 发送消息它使用 stomper 包.stomper 包只生成消息"字符串,您只需使用 ws.send(message)

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 配置:

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
    }

}

在代码的 Python 客户端:

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)

现在 d 将是一个 Stomp 格式的消息,它有一个非常简单的格式.MSG 是我为解析它而编写的一个快速而肮脏的类.

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

        self.message = ''.join(sp[7:])[0:-1]  # take the last part of the message minus the last character which is 0

这不是最完整的解决方案.没有取消订阅,Stomp 订阅的 id 是随机生成的,而不是记住的".但是,stomper 库为您提供了创建退订消息的能力.

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.

服务器端发送到 /something-to-subscribe-to 的任何内容都将被所有订阅它的 Python 客户端接收.

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");
        }
    }

}

相关文章