Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring Boot 4.3.5带jwt授权的WebSocket聊天。GenericMessage中没有目标_Spring_Spring Boot_Ionic3_Spring Websocket - Fatal编程技术网

Spring Boot 4.3.5带jwt授权的WebSocket聊天。GenericMessage中没有目标

Spring Boot 4.3.5带jwt授权的WebSocket聊天。GenericMessage中没有目标,spring,spring-boot,ionic3,spring-websocket,Spring,Spring Boot,Ionic3,Spring Websocket,我正在尝试为一个带有spring boot后端的移动应用程序(ionic 3)实现1-1聊天。似乎遇到了一些配置问题 无法发送消息,可能是因为未创建目标频道 后端: @RestController public class ChatController { @Autowired private PrivateChatService privateChatService; private final static Logger logger = LogManager.ge

我正在尝试为一个带有spring boot后端的移动应用程序(ionic 3)实现1-1聊天。似乎遇到了一些配置问题

无法发送消息,可能是因为未创建目标频道

后端:

@RestController
public class ChatController {
    @Autowired
    private PrivateChatService privateChatService;

    private final static Logger logger = LogManager.getLogger(ChatController.class.getName());


    @RequestMapping(value = "/chat/messages/{item_id}/chat_with/{buyer_login}", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> getExistingChatMessages(@PathVariable("item_id") String itemId, @PathVariable("buyer_login") String buyerLogin) {
        List<ChatMessage> messages = privateChatService.getExistingChatMessages(itemId, buyerLogin);

        logger.info("Here get messages");
        return JSONResponseHelper.createResponse(messages, HttpStatus.OK);
    }


    @MessageMapping("/chat/{item_id}/send")
    @SendTo("/topic/chat/{item_id}/chat_with/{buyer_login}")
    public ChatMessage send(@Payload ChatMessage message,
                            @DestinationVariable("item_id") String item_id) throws Exception {
//        logger.info(principal.getName());
        logger.info(message.toString());
        logger.info(item_id);
        privateChatService.submitMessage(message);
        return message;
    }

}
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private final static Logger logger = LogManager.getLogger(WebSocketConfig.class.getName());

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private PrivateChatService privateChatService;

    private static final String MESSAGE_PREFIX = "/topic";
    private static final String END_POINT = "/chat";
    private static final String APPLICATION_DESTINATION_PREFIX = "/live";


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        if (registry != null) {
            registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        if (registry != null) {
            registry.enableSimpleBroker(MESSAGE_PREFIX);
            registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX);
        }
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String authToken = accessor.getFirstNativeHeader("Authentication");
                    String jwt = JwtUtils.resolveToken(authToken);
                    if (jwtTokenProvider.validateToken(jwt)) {
                        Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                        accessor.setUser(authentication);
                        String itemId = accessor.getFirstNativeHeader("item_id");
                        accessor.setDestination("/topic" + privateChatService.getChannelId(itemId, authentication.getName()));
                        logger.info(accessor.getDestination()); //ex: /topic/chat/3434/chat_with/user3797474342423
                    }
                }
                return message;
            }
        });
    }
}
 private _initWebsock(auth_token:string, item_id: number) {
    let headers: Object = {
      Authentication: `Bearer ${auth_token}`,
      item_id: item_id
    };

    this.stomp.configure({
      host :this.websocketApi + 'chat',
      headers: headers,
      queue:{'init':false}
    });

    console.log("Connecting stomp socket...");

    //start connection
    this.stomp.startConnect().then(() => {
      this.stomp.done('init');
      console.log('connected');

      //subscribe
      this.subscription = this.stomp.subscribe(`/chat/${item_id}/`, this.socketListener);
    });
  }
  public socketListener = (data) => {
    console.log(data)
  };

  send(msg: ChatMessage, item_id: number){
    //send data

    console.log(msg);
    this.stomp.send(`/live/chat/${item_id}/send`, {}, JSON.stringify(msg));
  }
聊天室控制器:

@RestController
public class ChatController {
    @Autowired
    private PrivateChatService privateChatService;

    private final static Logger logger = LogManager.getLogger(ChatController.class.getName());


    @RequestMapping(value = "/chat/messages/{item_id}/chat_with/{buyer_login}", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> getExistingChatMessages(@PathVariable("item_id") String itemId, @PathVariable("buyer_login") String buyerLogin) {
        List<ChatMessage> messages = privateChatService.getExistingChatMessages(itemId, buyerLogin);

        logger.info("Here get messages");
        return JSONResponseHelper.createResponse(messages, HttpStatus.OK);
    }


    @MessageMapping("/chat/{item_id}/send")
    @SendTo("/topic/chat/{item_id}/chat_with/{buyer_login}")
    public ChatMessage send(@Payload ChatMessage message,
                            @DestinationVariable("item_id") String item_id) throws Exception {
//        logger.info(principal.getName());
        logger.info(message.toString());
        logger.info(item_id);
        privateChatService.submitMessage(message);
        return message;
    }

}
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private final static Logger logger = LogManager.getLogger(WebSocketConfig.class.getName());

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private PrivateChatService privateChatService;

    private static final String MESSAGE_PREFIX = "/topic";
    private static final String END_POINT = "/chat";
    private static final String APPLICATION_DESTINATION_PREFIX = "/live";


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        if (registry != null) {
            registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        if (registry != null) {
            registry.enableSimpleBroker(MESSAGE_PREFIX);
            registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX);
        }
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String authToken = accessor.getFirstNativeHeader("Authentication");
                    String jwt = JwtUtils.resolveToken(authToken);
                    if (jwtTokenProvider.validateToken(jwt)) {
                        Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                        accessor.setUser(authentication);
                        String itemId = accessor.getFirstNativeHeader("item_id");
                        accessor.setDestination("/topic" + privateChatService.getChannelId(itemId, authentication.getName()));
                        logger.info(accessor.getDestination()); //ex: /topic/chat/3434/chat_with/user3797474342423
                    }
                }
                return message;
            }
        });
    }
}
 private _initWebsock(auth_token:string, item_id: number) {
    let headers: Object = {
      Authentication: `Bearer ${auth_token}`,
      item_id: item_id
    };

    this.stomp.configure({
      host :this.websocketApi + 'chat',
      headers: headers,
      queue:{'init':false}
    });

    console.log("Connecting stomp socket...");

    //start connection
    this.stomp.startConnect().then(() => {
      this.stomp.done('init');
      console.log('connected');

      //subscribe
      this.subscription = this.stomp.subscribe(`/chat/${item_id}/`, this.socketListener);
    });
  }
  public socketListener = (data) => {
    console.log(data)
  };

  send(msg: ChatMessage, item_id: number){
    //send data

    console.log(msg);
    this.stomp.send(`/live/chat/${item_id}/send`, {}, JSON.stringify(msg));
  }
移动客户端,ng2 stomp服务:

@RestController
public class ChatController {
    @Autowired
    private PrivateChatService privateChatService;

    private final static Logger logger = LogManager.getLogger(ChatController.class.getName());


    @RequestMapping(value = "/chat/messages/{item_id}/chat_with/{buyer_login}", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> getExistingChatMessages(@PathVariable("item_id") String itemId, @PathVariable("buyer_login") String buyerLogin) {
        List<ChatMessage> messages = privateChatService.getExistingChatMessages(itemId, buyerLogin);

        logger.info("Here get messages");
        return JSONResponseHelper.createResponse(messages, HttpStatus.OK);
    }


    @MessageMapping("/chat/{item_id}/send")
    @SendTo("/topic/chat/{item_id}/chat_with/{buyer_login}")
    public ChatMessage send(@Payload ChatMessage message,
                            @DestinationVariable("item_id") String item_id) throws Exception {
//        logger.info(principal.getName());
        logger.info(message.toString());
        logger.info(item_id);
        privateChatService.submitMessage(message);
        return message;
    }

}
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private final static Logger logger = LogManager.getLogger(WebSocketConfig.class.getName());

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private PrivateChatService privateChatService;

    private static final String MESSAGE_PREFIX = "/topic";
    private static final String END_POINT = "/chat";
    private static final String APPLICATION_DESTINATION_PREFIX = "/live";


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        if (registry != null) {
            registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        if (registry != null) {
            registry.enableSimpleBroker(MESSAGE_PREFIX);
            registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX);
        }
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String authToken = accessor.getFirstNativeHeader("Authentication");
                    String jwt = JwtUtils.resolveToken(authToken);
                    if (jwtTokenProvider.validateToken(jwt)) {
                        Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                        accessor.setUser(authentication);
                        String itemId = accessor.getFirstNativeHeader("item_id");
                        accessor.setDestination("/topic" + privateChatService.getChannelId(itemId, authentication.getName()));
                        logger.info(accessor.getDestination()); //ex: /topic/chat/3434/chat_with/user3797474342423
                    }
                }
                return message;
            }
        });
    }
}
 private _initWebsock(auth_token:string, item_id: number) {
    let headers: Object = {
      Authentication: `Bearer ${auth_token}`,
      item_id: item_id
    };

    this.stomp.configure({
      host :this.websocketApi + 'chat',
      headers: headers,
      queue:{'init':false}
    });

    console.log("Connecting stomp socket...");

    //start connection
    this.stomp.startConnect().then(() => {
      this.stomp.done('init');
      console.log('connected');

      //subscribe
      this.subscription = this.stomp.subscribe(`/chat/${item_id}/`, this.socketListener);
    });
  }
  public socketListener = (data) => {
    console.log(data)
  };

  send(msg: ChatMessage, item_id: number){
    //send data

    console.log(msg);
    this.stomp.send(`/live/chat/${item_id}/send`, {}, JSON.stringify(msg));
  }
问题1(可能):

@RestController
public class ChatController {
    @Autowired
    private PrivateChatService privateChatService;

    private final static Logger logger = LogManager.getLogger(ChatController.class.getName());


    @RequestMapping(value = "/chat/messages/{item_id}/chat_with/{buyer_login}", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> getExistingChatMessages(@PathVariable("item_id") String itemId, @PathVariable("buyer_login") String buyerLogin) {
        List<ChatMessage> messages = privateChatService.getExistingChatMessages(itemId, buyerLogin);

        logger.info("Here get messages");
        return JSONResponseHelper.createResponse(messages, HttpStatus.OK);
    }


    @MessageMapping("/chat/{item_id}/send")
    @SendTo("/topic/chat/{item_id}/chat_with/{buyer_login}")
    public ChatMessage send(@Payload ChatMessage message,
                            @DestinationVariable("item_id") String item_id) throws Exception {
//        logger.info(principal.getName());
        logger.info(message.toString());
        logger.info(item_id);
        privateChatService.submitMessage(message);
        return message;
    }

}
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private final static Logger logger = LogManager.getLogger(WebSocketConfig.class.getName());

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private PrivateChatService privateChatService;

    private static final String MESSAGE_PREFIX = "/topic";
    private static final String END_POINT = "/chat";
    private static final String APPLICATION_DESTINATION_PREFIX = "/live";


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        if (registry != null) {
            registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        if (registry != null) {
            registry.enableSimpleBroker(MESSAGE_PREFIX);
            registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX);
        }
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String authToken = accessor.getFirstNativeHeader("Authentication");
                    String jwt = JwtUtils.resolveToken(authToken);
                    if (jwtTokenProvider.validateToken(jwt)) {
                        Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                        accessor.setUser(authentication);
                        String itemId = accessor.getFirstNativeHeader("item_id");
                        accessor.setDestination("/topic" + privateChatService.getChannelId(itemId, authentication.getName()));
                        logger.info(accessor.getDestination()); //ex: /topic/chat/3434/chat_with/user3797474342423
                    }
                }
                return message;
            }
        });
    }
}
 private _initWebsock(auth_token:string, item_id: number) {
    let headers: Object = {
      Authentication: `Bearer ${auth_token}`,
      item_id: item_id
    };

    this.stomp.configure({
      host :this.websocketApi + 'chat',
      headers: headers,
      queue:{'init':false}
    });

    console.log("Connecting stomp socket...");

    //start connection
    this.stomp.startConnect().then(() => {
      this.stomp.done('init');
      console.log('connected');

      //subscribe
      this.subscription = this.stomp.subscribe(`/chat/${item_id}/`, this.socketListener);
    });
  }
  public socketListener = (data) => {
    console.log(data)
  };

  send(msg: ChatMessage, item_id: number){
    //send data

    console.log(msg);
    this.stomp.send(`/live/chat/${item_id}/send`, {}, JSON.stringify(msg));
  }
在浏览器控制台中,它显示客户端订阅的是
/chat/item\u id
,而不是
/topic/chat/3434/chat\u和/user37974743423
=>似乎
configureClientInboundChannel
不起作用

问题2:

@RestController
public class ChatController {
    @Autowired
    private PrivateChatService privateChatService;

    private final static Logger logger = LogManager.getLogger(ChatController.class.getName());


    @RequestMapping(value = "/chat/messages/{item_id}/chat_with/{buyer_login}", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> getExistingChatMessages(@PathVariable("item_id") String itemId, @PathVariable("buyer_login") String buyerLogin) {
        List<ChatMessage> messages = privateChatService.getExistingChatMessages(itemId, buyerLogin);

        logger.info("Here get messages");
        return JSONResponseHelper.createResponse(messages, HttpStatus.OK);
    }


    @MessageMapping("/chat/{item_id}/send")
    @SendTo("/topic/chat/{item_id}/chat_with/{buyer_login}")
    public ChatMessage send(@Payload ChatMessage message,
                            @DestinationVariable("item_id") String item_id) throws Exception {
//        logger.info(principal.getName());
        logger.info(message.toString());
        logger.info(item_id);
        privateChatService.submitMessage(message);
        return message;
    }

}
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    private final static Logger logger = LogManager.getLogger(WebSocketConfig.class.getName());

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private PrivateChatService privateChatService;

    private static final String MESSAGE_PREFIX = "/topic";
    private static final String END_POINT = "/chat";
    private static final String APPLICATION_DESTINATION_PREFIX = "/live";


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        if (registry != null) {
            registry.addEndpoint(END_POINT).setAllowedOrigins("*").withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        if (registry != null) {
            registry.enableSimpleBroker(MESSAGE_PREFIX);
            registry.setApplicationDestinationPrefixes(APPLICATION_DESTINATION_PREFIX);
        }
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(new ChannelInterceptorAdapter() {

            @Override
            public Message<?> preSend(Message<?> message, MessageChannel channel) {
                StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    String authToken = accessor.getFirstNativeHeader("Authentication");
                    String jwt = JwtUtils.resolveToken(authToken);
                    if (jwtTokenProvider.validateToken(jwt)) {
                        Authentication authentication = jwtTokenProvider.getAuthentication(jwt);
                        accessor.setUser(authentication);
                        String itemId = accessor.getFirstNativeHeader("item_id");
                        accessor.setDestination("/topic" + privateChatService.getChannelId(itemId, authentication.getName()));
                        logger.info(accessor.getDestination()); //ex: /topic/chat/3434/chat_with/user3797474342423
                    }
                }
                return message;
            }
        });
    }
}
 private _initWebsock(auth_token:string, item_id: number) {
    let headers: Object = {
      Authentication: `Bearer ${auth_token}`,
      item_id: item_id
    };

    this.stomp.configure({
      host :this.websocketApi + 'chat',
      headers: headers,
      queue:{'init':false}
    });

    console.log("Connecting stomp socket...");

    //start connection
    this.stomp.startConnect().then(() => {
      this.stomp.done('init');
      console.log('connected');

      //subscribe
      this.subscription = this.stomp.subscribe(`/chat/${item_id}/`, this.socketListener);
    });
  }
  public socketListener = (data) => {
    console.log(data)
  };

  send(msg: ChatMessage, item_id: number){
    //send data

    console.log(msg);
    this.stomp.send(`/live/chat/${item_id}/send`, {}, JSON.stringify(msg));
  }
尝试执行
this.stomp.send(
/live/chat/${item_id}/send
,{},JSON.stringify(msg)),正在获取
o.s.m.s.b.DefaultSubscriptionRegistry:GenericMessage[payload=byte[2],Header={simpMessageType=MESSAGE….
错误。

我就是这样解决这个问题的:

当用户使用Spring Security进行身份验证时,WebSocket模块将创建 基于其主体的该用户的唯一通道。示例 “/user/queue/position updates”被转换为 “/queue/position-updates-user123”

所以在客户端,我所要做的就是订阅 /用户/队列/请求

在服务器端,将消息发送到 /用户/{username}/queue/请求 convertAndSendToUser(request.getFromUser(),“/queue/requests”, 请求)和Spring处理其余部分


您好,关于如何将消息重定向到特定用户,还不清楚,但您也可以检查这一点。您是否可以在发送消息时在控制台中共享STOMP输出以及完整的错误?我想,如果创建了频道,我想这应该在控制器注释中起作用?
@SendTo(“/topic/chat/{item_id}/chat_with/{buyer\u login}”)
但我在GenericMessage中没有得到目的地,如主题中所述