我正在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作为使用logging_user_email的参考,但这不起作用。
我已经尝试在客户端添加/user
前缀以订阅/user/topic/notification/
,如this answer中所述。我也尝试使用queue
代替同一答案中说明的主题,但没有成功。
我找到的其他答案提到在控制器中使用@MessageMapping
,但我需要能够从服务发送通知。
所以问题是,如何区分通知的目标用户以及如何在服务器端和客户端定义此通知?
答案 0 :(得分:0)
这可能会有点晚,但是对于遇到相同问题的任何人,我都可以通过执行以下操作使其起作用:
我没有发送用户的电子邮件,而是将其转换为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
});
其他所有与tututial中相同。