在Spring Boot WebSocket中向特定用户发送通知

17
我希望向特定客户端发送通知。 例如用户名用户。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration extends
    AbstractWebSocketMessageBrokerConfigurer {

        @Override
        public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
            stompEndpointRegistry.addEndpoint("/socket")
                    .setAllowedOrigins("*")
                    .withSockJS();
        }

        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.enableSimpleBroker("/topic", "/queue");
            registry.setApplicationDestinationPrefixes("/app");

        }

控制器

@GetMapping("/notify")
public String getNotification(Principal principal) {
    String username = "user";

    notifications.increment();
    logger.info("counter" + notifications.getCount() + "" + principal.getName());
    //  logger.info("usersend:"+sha.getUser().getName()) ; //user

    template.convertAndSendToUser(principal.getName(), "queue/notification", notifications);

    return "Notifications successfully sent to Angular !";
}

客户端

Angular服务

connect() {
    let socket = new SockJs(`api/socket`);

    let stompClient = Stomp.over(socket);

    return stompClient;
}

Angular组件

 let stompClient = this.webSocketService.connect();

     stompClient.connect({}, frame => {

      stompClient.subscribe('/user/queue/notification', notifications => {
               console.log('test'+notifications)
          this.notifications = JSON.parse(notifications.body).count;

      })     });

我已经搜索了许多其他的问题并尝试过,但是它们都对我没有用。例如这里被Thanh Nguyen Van回答和 这里

控制台

 Opening Web Socket...
    stomp.js:134 Web Socket Opened...
    stomp.js:134 >>> CONNECT
    accept-version:1.1,1.0
    heart-beat:10000,10000


    stomp.js:134 <<< CONNECTED
    version:1.1
    heart-beat:0,0


    stomp.js:134 connected to server undefined
    reminder.component.ts:18 test callsed
    stomp.js:134 >>> SUBSCRIBE
    id:sub-0
    destination:/user/queue/notification

提前致谢。


我已经实现了stomp,并且它正在工作,问题是当我关闭服务器时,我会收到一个警告——Web应用程序[ROOT]似乎已经启动了一个名为[MessageBroker-4]的线程,但未能停止它。这很可能会导致内存泄漏。 - krr
2个回答

12
gerrytanSending message to specific user on Spring Websocket的回答提到了一个Web Socket配置更改,以注册/user前缀。在您的情况下,我猜这意味着替换。
registry.enableSimpleBroker("/topic", "/queue");

with

registry.enableSimpleBroker("/topic", "/queue", "/user");

他还说在控制器中你不需要/user前缀,因为它会自动添加。所以你可以尝试这样做:
template.convertAndSendToUser(principal.getName(), "/queue/notification", notifications);

和这个:

template.convertAndSendToUser(principal.getName(), "/user/queue/notification", notifications);

在客户端上,您需要提供用于连接服务器的用户名。 您可以直接插入它:

stompClient.subscribe('/user/naila/queue/notification', ...)

或从头文件中获取。但Markus如何向特定用户发送websocket消息?中表示,即使在这里也不需要用户名,因此它可能像这样工作:

stompClient.subscribe('/user/queue/notification', ...)

我们该如何处理特定用户的WebSocket连接关闭? - krr
有什么需要处理的吗?如何关闭特定用户的连接?无论如何,这与原始帖子无关,你应该将其作为一个独立的问题发布。 - edixon
嗨edixon,你的回答非常有帮助。我已经实现了stomp,并且它正在工作,问题是当我关闭服务器时,我会收到一个警告--Web应用程序[ROOT]似乎已经启动了一个名为[MessageBroker-4]的线程,但未能停止它。这很可能会导致内存泄漏。 - krr
您的问题在这里有几个答案:https://dev59.com/oVYM5IYBdhLWcg3w3jE4. 当我搜索“网页应用程序似乎已启动”时,我在顶部找到了它。 - edixon
你好,谢谢提供链接,但是它讨论了其他问题。在你实施解决方案后,本地终止应用程序时,你没有收到任何线程或内存泄漏警告吗? - krr

7
似乎您在目标路径中缺少了一个斜杠:
template.convertAndSendToUser(principal.getName(), "/queue/notification", notifications); 

请查看Spring Websocket Chat示例,可能会对您有所帮助 https://github.com/salmar/spring-websocket-chat - Sergi Almar
在Spring中,我能否找到由此行生成的路径?template.convertAndSendToUser(.....)? - naila naseem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接