Spring Boot中的多播Websockets

时间:2018-06-16 15:52:43

标签: java spring spring-boot authentication websocket

上下文

第一次在春天使用websockets。我的应用程序涉及一种类型的用户(CHAP),将其当前位置提供给所有其他订阅者(USR)(并且有权订阅此信息)

我正在阅读文档,并找到this部分,我认为这部分是我的解决方案,但我不是100%确定它是如何工作的,并且会喜欢有更强理解力的人换句话说。我已经看到类似的堆栈溢出问题,但解决方案感觉太具体了(虽然这可能只是我自己缺乏理解)。

问题

每个主题可以发布其位置到主题的一个CHAP。 用户可以订阅他们授权订阅的任何主题。

基本上是这样的:

  • 变量端点的多个主题(类似于/ {route_id} / location)

  • 用户可以订阅这些主题并在可用时接收更新

  • 具有CHAP角色的用户可以发布到一个主题。 (即每个CHAP都有一个可以发布到的{route_id}。

  • 具有USR角色的用户可以收听他们所属的多个主题(即每个USR都有多条路线可以监听更新)

这与具有多个聊天室的问题类似,这是websockets的常见示例。但是,我找到的所有示例都有静态聊天室名称,单个聊天室,或者只能将消息定位到一个用户(不是一个组)

当前代码

@MessageMapping("/chaperone/location") // chaperone sends data to here
@SendTo("/{route_id}/location") // users can listen in on this
public BusModel updateLocation(@DestinationVariable long route_id, BusModel busModel) {
    return routeService.updateBusLocation(busModel);
}

我的想法是,伴侣会发布到该网址,所有订阅他们路线的用户都会获得更新。

谢谢!

1 个答案:

答案 0 :(得分:1)

This原来是一个解决方案,并且不需要我以前认为的太多配置。这是我的版本:

WebSocketConfig

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    public static final String TOPIC="/topic";

    /**
     * Consumers connect to endpoint/live to connect to the websocket
     *
     * @param registry
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/live").setAllowedOrigins("*").withSockJS();
    }

    /**
     * Once connected to the websocket, users can subscribe to endpoints prefixed with /topic
     * as these are managed by the message broker.
     * @param registry
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker(TOPIC);
        registry.setApplicationDestinationPrefixes("/");
    }
}

LiveController

@SubscribeMapping(TOPIC + "/routes/{route_id}")
public MessageWrapper subscribeToRouteLocation(
        @DestinationVariable(value = "route_id") long route_id) {
    LOG.debug("New user subscribed to location of route %d", route_id);
    return new MessageWrapper(LOCATION_MESSAGE, routeService.getBusForRoute(route_id));
}

@MessageMapping("/routes/{route_id}")
@SendTo(TOPIC + "/routes/{route_id}")
public MessageWrapper updateRouteLocation(
        @DestinationVariable(value = "route_id") long route_id,
        @Payload BusStatusUpdateModel busLocation) {
    if (busLocation.getLat() == 0 && busLocation.getLon() == 0) {
        LOG.debug("Ending route %d", route_id);
        return new MessageWrapper(ROUTE_TERMINATED_MESSAGE, routeService.endBusForRoute(route_id));
    } else {
        LOG.debug("Updating location of route %d", route_id);
        BusStatusUpdateModel statusUpdateModel = routeService.updateBusLocation(busLocation, route_id);
        return new MessageWrapper(LOCATION_MESSAGE, statusUpdateModel);
    }
}

因此,发送到/ routes / {route_id}的邮件将传递给/ topic / routes / {route_id}的订户

我尚未测试授权内容,一旦获得授权,将其填写!