语境

Spring 第一次使用websockets。我的应用程序涉及一种用户(CHAP),将其当前位置提供给所有其他已订阅(USR)(并被授权订阅此信息)的用户

我正在阅读文档,并找到了this部分,我相信它可以解决我的问题,但是我不确定100%确切地知道它如何工作,而是希望有人对它有更深入的了解。我已经在堆栈溢出中看到了类似的问题,但是解决方案感觉太具体了(尽管这可能只是我自己缺乏了解)。

问题

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

所以本质上:

  • 可变端点处的多个主题(类似于/{route_id}/location)
  • 用户可以订阅这些主题,并在可用时接收更新。
  • 具有CHAP角色的用户可以发布到一个主题。 (即每个CHAP都有一个可以发布到的{route_id}。
  • 具有USR角色的用户可以收听他们所属的多个主题(即,每个USR具有可以收听其更新的多个路由)

  • 这类似于拥有多个聊天室的问题,这是Websocket的常见示例。但是,我可以找到的所有示例都具有静态聊天室名称,单个聊天室,或者只能将消息定向给一个用户(而不是一组用户)

    当前代码
    @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);
    }
    

    我在这里的想法是,伴侣将张贴到该URL,并且所有订阅其路线的用户都将得到更新。

    谢谢!

    最佳答案

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

    WebSocket配置

    @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}的订户

    我尚未测试授权内容,一旦拥有它便将其填写!

    09-25 16:55