在我的应用程序中,我需要向特定用户发送实时通知。我的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
?
我经历了几个与此相关的问题,但我并不清楚这些概念。
这个username
是java.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");
}
在向用户发送任何消息之前,您需要先由服务器对其进行身份验证。这样做有不同的方法。 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();