gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 13:47:31 29 4
gpt4 key购买 nike

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

无法发送消息可能是因为没有创建目标 channel

后端:

聊天 Controller :

@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;
}

}

WebSocketConfig:

@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;
}
});
}
}

WebSocketSecurityConfig

@Configuration
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected boolean sameOriginDisabled() {
return true;
}
}

移动客户端,ng2-stomp-service:

 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(可能):

在浏览器控制台中,它显示客户端订阅 /chat/item_id 而不是 /topic/chat/3434/chat_with/user3797474342423 => 看起来像 configureClientInboundChannel 不起作用?

问题 2:

当尝试执行 this.stomp.send(/live/chat/${item_id}/send, {}, JSON.stringify(msg)); , 得到o.s.m.s.b.DefaultSubscriptionRegistry : GenericMessage [payload=byte[2], headers={simpMessageType=MESSAGE.... 错误。

最佳答案

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-authentication

https://stackoverflow.com/a/33962402/8336511

这就是我解决这个问题的方法:

When user authenticates with Spring Security, WebSocket module creates unique channel for that user based on his Principal. Example "/user/queue/position-updates" is translated to "/queue/position-updates-user123"

So on the client side all I had to do, was subscribe to /user/queue/requests

And on the server side, send messages to /user/{username}/queue/requests with convertAndSendToUser(request.getFromUser(), "/queue/requests", request) and Spring handles the rest.

关于带有 jwt 授权的 Spring Boot 4.3.5 WebSocket 聊天。 GenericMessage 中没有目的地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48877418/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com