【问题标题】:Notify specific user using web socket in spring boot在 Spring Boot 中使用 Web 套接字通知特定用户
【发布时间】:2019-08-16 12:06:00
【问题描述】:

我正在 Spring Boot 中创建一个任务管理应用程序。以下是我的模型:

public class Task {

    private String name;
    private String description;
    private User assignee;

    //getters and setters
}

public class User {

    private String name;
    private String email;
    private String password;

    //getters and setters
}

我正在为用户使用 Spring Security。现在说有三个Users A、B 和C。A 创建一个Task 并将其分配给B。此时我正在尝试使用websocket 仅向B 发送通知。为此我创建了一个WebSocketConfiguration

@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");
        registry.setApplicationDestinationPrefixes("/app");
    }
}

分配此任务的控制器:

@RestController
@RequestMapping("/api/task")
public class TaskController {

    @PostMapping("/assign")
    public void assign(@RequestBody Task task) {
        taskService.assign(task);
    }
}

最后在服务中,我有:

@Service
public class TaskService {

    @Autowired
    private SimpMessagingTemplate template;

    @Override
    public void assign(Task task) {
        //logic to assign task
        template.convertAndSendToUser(task.getAssignee().getEmail(), "/topic/notification",
            "A task has been assigned to you");
    }
}

在客户端,我使用的是 Angular,订阅部分如下所示:

stompClient.subscribe('/topic/notification'+logged_user_email, notifications => {
    console.log(notifications); 
})

目前,控制台中不会为任何用户打印任何内容。

我遵循this 教程,该教程非常适合广播消息。

我还使用了this answer 作为使用logged_user_email 的参考,但它不起作用。

我已尝试在客户端添加前缀 /user 以订阅 /user/topic/notification/,如 this answer 中所述。我也尝试过使用 queue 而不是主题,如同一答案中所述,但没有成功。

我发现的其他答案提到了在控制器中使用@MessageMapping,但我需要能够从服务发送通知。

所以问题是我如何区分通知的目标用户以及如何在服务器端和客户端定义它?

【问题讨论】:

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


    【解决方案1】:

    这可能有点晚了,但对于遇到同样问题的任何人,我通过执行以下操作使其工作:

    我没有发送用户的电子邮件,而是将其转换为 Base64 并发送。

    @Service
    public class TaskService {
    
        @Autowired
        private SimpMessagingTemplate template;
    
        @Override
        public void assign(Task task) {
            //logic to assign task
            String base64EncodedEmail = Base64.getEncoder().encodeToString(task.getAssignee().getEmail().getBytes(StandardCharsets.UTF_8));
            template.convertAndSendToUser(base64EncodedEmail, "/topic/notification",
                "A task has been assigned to you");
        }
    }
    

    然后在客户端,this tutorial的WebSocketService中,我将connect方法替换为如下:

    public connect() {
        const encodedEmail = window.btoa(email);
        const socket = new SockJs(`http://localhost:8080/socket?token=${encodedEmail}`);
        const stompClient = Stomp.over(socket);
        return stompClient;
    }
    

    在订阅部分,我做了以下操作:

    stompClient.subscribe("/user/topic/notification", notification => {
        //logic to display notification
    });
    

    其他内容与教程中的相同。

    【讨论】:

      猜你喜欢
      • 2019-02-14
      • 2018-09-19
      • 2018-05-19
      • 2017-12-09
      • 2016-03-06
      • 2021-06-26
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多