Spring 启动原始 WebSocket 设置主体
Spring Boot Raw WebSocket Set Principal
我想用 Spring Boot 开发实时通知发送器,但我不能使用 Stomp 和 sockjs,所以我需要实现原始 WebSocket,但我找不到如何在 WebSocket 中设置 Principal连接因为我想使用 JWT 令牌进行身份验证。那么,我在哪里或如何设置主体。
我正在使用这些;
WebSocketConfig.java :
@EnableWebSocket
@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
WebSocketNotificationSenderService senderService;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry
webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(createHandler(),
"/handler").addInterceptors(new HttpSessionHandshakeInterceptor()
{
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
@Nullable Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response,
wsHandler, attributes)
}
});
}
@Bean
public WebSocketHandler createHandler() {
return new MyHandler(senderService);
}
}
MyHandler.java :
@Component
public class MyHandler extends TextWebSocketHandler {
WebSocketNotificationSenderService senderService;
public MyHandler(WebSocketNotificationSenderService senderService){
this.senderService = senderService;
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
senderService.addToSession(session);
}
}
WebSocketNotificationSenderService.java :
@Service
public class WebSocketNotificationSenderService implements
IWebSocketSenderService<WrapperWsNotification> {
private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
private ObjectMapper mapper = new ObjectMapper();
public void addToSession(WebSocketSession session) {
sessions.add(session);
}
@Override
public void convertAndSend(WrapperWsNotification payload) throws JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.stream().forEach(session -> {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
});
}
@Override
public void convertAndSendToUser(String user, WrapperWsNotification payload) throws
JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.forEach(session -> {
if (session.getPrincipal().getName().equals(user)) {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
我到 websocket 的通知发送者;
@Component
public class NotificationConsumer {
@Autowired
WebSocketNotificationSenderService webSocket;
private Logger logger = LoggerFactory.getLogger(NotificationConsumer.class);
public void onReceiveNotification(String object) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
WrapperWsNotification wrapperWsNotification= objectMapper.readValue(object, WrapperWsNotification.class);
logger.info("User where coming from redis " + wrapperWsNotification.getUser().getUsername());
webSocket.convertAndSendToUser(wrapperWsNotification.getUser().getUsername(), wrapperWsNotification);
}
}
我找到了解决方案并添加了一个example
我想用 Spring Boot 开发实时通知发送器,但我不能使用 Stomp 和 sockjs,所以我需要实现原始 WebSocket,但我找不到如何在 WebSocket 中设置 Principal连接因为我想使用 JWT 令牌进行身份验证。那么,我在哪里或如何设置主体。 我正在使用这些;
WebSocketConfig.java :
@EnableWebSocket
@Configuration
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
WebSocketNotificationSenderService senderService;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry
webSocketHandlerRegistry) {
webSocketHandlerRegistry.addHandler(createHandler(),
"/handler").addInterceptors(new HttpSessionHandshakeInterceptor()
{
@Override
public void afterHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
@Nullable Exception ex) {
super.afterHandshake(request, response, wsHandler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
return super.beforeHandshake(request, response,
wsHandler, attributes)
}
});
}
@Bean
public WebSocketHandler createHandler() {
return new MyHandler(senderService);
}
}
MyHandler.java :
@Component
public class MyHandler extends TextWebSocketHandler {
WebSocketNotificationSenderService senderService;
public MyHandler(WebSocketNotificationSenderService senderService){
this.senderService = senderService;
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
senderService.addToSession(session);
}
}
WebSocketNotificationSenderService.java :
@Service
public class WebSocketNotificationSenderService implements
IWebSocketSenderService<WrapperWsNotification> {
private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
private ObjectMapper mapper = new ObjectMapper();
public void addToSession(WebSocketSession session) {
sessions.add(session);
}
@Override
public void convertAndSend(WrapperWsNotification payload) throws JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.stream().forEach(session -> {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
});
}
@Override
public void convertAndSendToUser(String user, WrapperWsNotification payload) throws
JsonProcessingException {
String payloadString = mapper.writeValueAsString(payload);
sessions.forEach(session -> {
if (session.getPrincipal().getName().equals(user)) {
try {
session.sendMessage(new TextMessage(payloadString));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
我到 websocket 的通知发送者;
@Component
public class NotificationConsumer {
@Autowired
WebSocketNotificationSenderService webSocket;
private Logger logger = LoggerFactory.getLogger(NotificationConsumer.class);
public void onReceiveNotification(String object) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
WrapperWsNotification wrapperWsNotification= objectMapper.readValue(object, WrapperWsNotification.class);
logger.info("User where coming from redis " + wrapperWsNotification.getUser().getUsername());
webSocket.convertAndSendToUser(wrapperWsNotification.getUser().getUsername(), wrapperWsNotification);
}
}
我找到了解决方案并添加了一个example