Клиент JavaScript подключается к конечной точке /WS, предоставляя токен JWT в заголовке авторизации. < /Li>
Канал -инчевов на сервере утверждает токен и устанавливает подбору пользователя (UUID) в качестве основного сеанса WebSockeocke. Подписывается на тему/пользователь/уведомления. UserId - это подставка пользователя.@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
@RequiredArgsConstructor
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final JwtDecoder jwtDecoder;
private final JwtAuthConverter jwtAuthConverter;
@Value("${oxyreimobile.oauth2.keycloak.realm}")
private String realm;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOriginPatterns("*") //TODO da modificare quando si saprà cosa mettere
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/user");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/user");
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new ChannelInterceptor() {
@Override
public Message preSend(Message message, MessageChannel channel) {
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
String authHeader = accessor.getFirstNativeHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
try {
Jwt jwt = jwtDecoder.decode(token);
Authentication authentication = jwtAuthConverter.convert(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
accessor.setUser(authentication);
System.out.println("
} catch (Exception e) {
throw new RuntimeException("JWT non valido: " + e.getMessage());
}
}
}
return message;
}
});
}
}
< /code>
В сервисе, которая делает бизнес -логику, я называю этот метод: < /p>
sendnotificationwebsocket(keycloakservices.getsub(emailcaregiver), n); < /li>
< /ul>
private void sendNotificationWebSocket(String userId, Notifications notifica) {
System.out.println("
sim.convertAndSendToUser(
userId,
"/notifications",
Map.of("content", "Nuova notifica: " + notifica.getSubject())
);
}
< /code>
Я создал пример фронта, показанный ниже: < /p>
Test WebSocket
Test WebSocket
const socket = new SockJS('http://localhost:8080/ws');
const client = Stomp.over(socket);
const token = "here the token jwt";
client.connect(
{ Authorization: `Bearer ${token}` }, // {
console.log('
client.subscribe(`/user/notifications`, msg => {
console.log("
});
},
error => console.error('
);
< /code>
Некоторые журналы в бэкэнд: < /p>
2025-09-19T23:29:26.755+02:00 DEBUG 10008 --- [app] [nio-8080-exec-5] s.w.s.h.LoggingWebSocketHandlerDecorator : New WebSocketServerSockJsSession[id=smnkzqoc]
2025-09-19T23:29:29.239+02:00 DEBUG 10008 --- [app] [nboundChannel-2] o.s.m.s.b.SimpleBrokerMessageHandler : Processing CONNECT session=smnkzqoc
2025-09-19T23:29:36.053+02:00 DEBUG 10008 --- [app] [nboundChannel-5] o.s.m.s.b.SimpleBrokerMessageHandler : Processing SUBSCRIBE /user/notifications id=sub-0 session=smnkzqoc
2025-09-19T23:29:43.693+02:00 INFO 10008 --- [app] [nio-8080-exec-2] c.m.o.o.s.impl.KeycloakServiceImpl : getSub of the username useruser@live.it
2025-09-19T23:29:43.920+02:00 DEBUG 10008 --- [app] [nio-8080-exec-2] o.s.m.s.b.SimpleBrokerMessageHandler : Processing MESSAGE destination=/user/71412206-e72d-478c-b1f2-4447f386424d/notifications session=null payload={"content":"Nuova notifica: E' presente un questionario da compilare"}
< /code>
Что не так с этим? Я хотел не помещать подписанную подзаготоку на ключевой категории на пути назначения с фронта, потому что я читал, что это то, что обрабатывается автоматически к весне, но я не могу заставить его работать.
Заранее!
Подробнее здесь: https://stackoverflow.com/questions/797 ... o-frontend