В моем приложении мне нужно отправлять уведомления в реальном времени конкретному пользователю.
Мой класс 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.info('Connected: ' + frame);
stompClient.subscribe('/topic/user', function (greeting) {
// showGreeting(JSON.parse(greeting.body).content);
console.info("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.
Вы можете проверить здесь для получения дополнительной информации о создании уникального идентификатора для каждого сеанса.
затем используйте это так:
@MessageMapping('/test')
public void test(SimpMessageHeaderAccessor sha)
{
String userName = sha.session.principal.name;
template.convertAndSend(userName, '/topic/user', "Hurray");
}
Я могу получить доступ к SimpMessageHeaderAccessor
с помощью метода, помеченного @MessageMapping('/test')
. Но я не получаю данные со стороны клиента. Я должен иметь возможность отправлять уведомления любому пользователю любым способом.
вы должны поддерживать уникальный идентификатор для каждого сеанса из клиентского запроса, а затем использовать метод convertAndSend
для push-уведомления для конкретного клиента с его идентификатором сеанса, который вы назначили ему.
И где я получу этот идентификатор? Не могли бы вы отредактировать свой ответ соответствующим образом
взять ссылку из stackoverflow.com/questions/37853727/…
Перед отправкой каких-либо сообщений пользователю необходимо сначала аутентифицировать его на сервере. Это можно сделать разными способами. 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();
Вы используете весеннюю безопасность?