【问题标题】:Real time notifications in spring boot web socketSpring Boot Web 套接字中的实时通知
【发布时间】:2019-02-14 04:33:29
【问题描述】:

在我的应用程序中,我需要向特定用户发送实时通知。 我的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吗?

标签: java spring spring-boot websocket spring-websocket


【解决方案1】:

在向用户发送任何消息之前,您需要先通过服务器对其进行身份验证。有不同的方法可以做到这一点。 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

【讨论】:

    【解决方案2】:

    usernamejava.security.Principal interface 的一部分。每个 StompHeaderAccessor 或 WebSocket 会话对象都有一个此原理的实例,您可以从中获取用户名。它不是自动生成的。 It has to be generated manually by the server for every session.

    您可以查看here 了解有关为每个会话生成唯一 ID 的更多信息。

    然后像这样使用:

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

    【讨论】:

    • 我可以通过@MessageMapping('/test') 注释的方法访问SimpMessageHeaderAccessor。但我没有从客户端接收数据。我应该能够通过任何方法向任何用户发送通知。
    • 您必须为来自客户端请求的每个会话维护一个唯一的 ID,然后使用 convertAndSend 方法为具有您分配给相同会话 ID 的特定客户端推送通知。
    • 我将在哪里获得该 ID?你能相应地编辑你的答案吗
    猜你喜欢
    • 2019-08-16
    • 2021-06-26
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2023-03-19
    • 1970-01-01
    • 2021-07-17
    相关资源
    最近更新 更多