使用react socket io和spring进行授权的websocket通信

yqkkidmi  于 2021-07-26  发布在  Java
关注(0)|答案(0)|浏览(347)

因此,我有一个使用springboot的api,并尝试实现一个websocket端点,用户在登录时可以在该端点获得订阅,并在该端点侦听不同实体创建的通知。假设我的websocket正在后台工作,下面是我的代码。

  1. @Configuration
  2. @EnableWebSocketMessageBroker
  3. public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
  4. @Override
  5. public void registerStompEndpoints(StompEndpointRegistry registry) {
  6. registry.addEndpoint("/points_notification")
  7. .setAllowedOrigins("localhost:3000")
  8. .withSockJS();
  9. }
  10. @Override
  11. public void configureMessageBroker(MessageBrokerRegistry registry) {
  12. registry.enableSimpleBroker("/topic");
  13. registry.setApplicationDestinationPrefixes("/app");
  14. }
  15. }
  1. @Controller
  2. public class NotificationsController {
  3. @Autowired private NotificationDispatcher dispatcher;
  4. @MessageMapping("/start")
  5. public void start(StompHeaderAccessor stompHeaderAccessor) {
  6. dispatcher.add(stompHeaderAccessor.getSessionId());
  7. System.out.println("GOT a session! " + stompHeaderAccessor.getSessionId());
  8. }
  9. @MessageMapping("/stop")
  10. public void stop(StompHeaderAccessor stompHeaderAccessor) {
  11. dispatcher.remove(stompHeaderAccessor.getSessionId());
  12. }
  13. }
  1. @Service
  2. public class NotificationDispatcher {
  3. @Autowired
  4. private SimpMessagingTemplate template;
  5. private final Set<String> listeners = new HashSet<>();
  6. public <T extends Serializable> void dispatch(T addedObj) {
  7. for (String listener : listeners) {
  8. LOG.info("Sending notification to " + listener);
  9. SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
  10. headerAccessor.setSessionId(listener);
  11. headerAccessor.setLeaveMutable(true);
  12. template.convertAndSendToUser(
  13. listener,
  14. "/topic/item",
  15. new ObjWithMsgResponse<T>("Point added by: " + listener, addedObj),
  16. headerAccessor.getMessageHeaders());
  17. }
  18. }
  19. //getters and event listeners
  20. }

当然了 dispatch() 在创建实体时被注入和调用。
在前面,我使用react并尝试处理与 socket.io-client ,我对这个有点陌生,所以我不太明白 emit 以及 on 方法是有效的,因为在文档中它们显示了您调用的和eventname,但是在spring中端点使用的是url,我在任何地方都找不到如何ping url而不是eventname。
我也试着用 SockJS 这就像一个咒语,但是端点需要身份验证,有了这个,我不能将这个头添加到socket请求中,soocket.io允许我这样做。
这是我的解决方案,它只连接但不接收或发出任何请求。

  1. class SocketManager {
  2. socketRef: Socket | undefined = undefined;
  3. startListening(authToken: String) {
  4. this.socketRef = io('http://localhost:11000/weblab4/', {
  5. path: "/weblab4" + '/points_notification',
  6. transports: ['websocket'],
  7. extraHeaders: {
  8. Authorization: "Bearer " + authToken
  9. }
  10. });
  11. this.socketRef.emit('/app/start', {});
  12. this.socketRef.on('/user/topic/item', (data: INewPointNotification) => {
  13. console.log("received data from socket: " + data);
  14. toast.success('? ' + data.msg + data.point, {/*toast props*/});
  15. });
  16. console.log("socket connected", this.socketRef);
  17. }
  18. stopListening() {
  19. if (this.socketRef !== undefined)
  20. this.socketRef.disconnect();
  21. console.log("socket disconnected", this.socketRef);
  22. }
  23. }

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题