Spring Boot Web Socket中的实时通知

5
在我的应用程序中,我需要向特定用户发送实时通知。 我的WebSocketConfig类如下所示,
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
        @Override
        public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
            stompEndpointRegistry.addEndpoint("/websocket-example")
                    .withSockJS();
        }

        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.enableSimpleBroker("/topic");
    }
}

大部分时候信息都是由服务器端发送的,因此我没有设置应用程序目标。

在客户端中,我正在订阅目标为'/topic/user'的内容。

function connect() {
    var socket = new SockJS('/websocket-example');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/user', function (greeting) {
//            showGreeting(JSON.parse(greeting.body).content);
console.log("Received message through WS");
        });
    });
}

在我的RestController中,我有一个方法,可以将消息广播到所有连接的客户端。

    @GetMapping("/test")
    public void test()
    {
        template.convertAndSend("/topic/user", "Hurray");
    }

直到这一部分,一切都很顺利。我收到了消息并记录在控制台中。
现在,如果我只想将通知发送给特定的用户,我必须使用template.convertAndSendToUser(String user, String destination, String message)。但是我不明白我应该传递什么给user参数。我在何时何地可以获得user
我浏览了几个相关的问题,但是我没有清楚地理解这些概念。

你正在使用Spring Security吗? - Solace
2个回答

2
在向用户发送任何消息之前,您需要首先通过服务器进行身份验证。有不同的方法可以实现此目的。Spring Security 是一个关键词。

https://docs.spring.io/spring-security/site/docs/current/guides/html5/helloworld-boot.html

完成身份验证后,您只需调用以下方法即可获取用户名:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();

https://www.baeldung.com/get-user-in-spring-security


0

这个usernamejava.security.Principal interface的一部分。每个StompHeaderAccessor或WebSocket会话对象都有一个此原则的实例,您可以从中获取用户名。它不是自动生成的。服务器必须为每个会话手动生成它。

您可以查看此处以获取有关为每个会话生成唯一ID的更多信息。

然后像这样使用:

@MessageMapping('/test')
public void test(SimpMessageHeaderAccessor sha)
{
  String userName = sha.session.principal.name;
  template.convertAndSend(userName, '/topic/user', "Hurray");
}

1
我可以在一个被注解为@MessageMapping('/test')的方法中访问SimpMessageHeaderAccessor。但是我没有从客户端接收到数据。我应该能够从任何方法向任何用户发送通知。 - Virat
你需要为每个客户端请求的会话维护一个唯一的ID,然后使用convertAndSend方法将通知推送给具有相同会话ID的特定客户端。 - Devratna
我该从哪里获取那个ID呢?您能否相应地编辑您的答案。 - Virat
请参考以下链接:https://dev59.com/sVoU5IYBdhLWcg3wEz-N - Devratna

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