我正在尝试使用弹簧启动后端为移动应用程序(离子3)实现1-1聊天。似乎遇到了一些配置问题。
无法发送消息可能是因为未创建目标频道
返回-结束:
ChatController:
@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
=&gt;似乎configureClientInboundChannel
不起作用?
问题2:
尝试执行this.stomp.send(
/ live / chat / $ {item_id} /发送, {}, JSON.stringify(msg));
时,获取
o.s.m.s.b.DefaultSubscriptionRegistry : No destination in GenericMessage [payload=byte[2], headers={simpMessageType=MESSAGE....
错误。
答案 0 :(得分:1)
和
https://stackoverflow.com/a/33962402/8336511
这就是我解决这个问题的方法:
当用户使用Spring Security进行身份验证时,WebSocket模块会创建 基于其Principal的该用户的唯一渠道。例 “/ user / queue / position-updates”已翻译为 “/队列/位置更新 - user123”
所以在客户端,所有我必须做的,是订阅 /用户/队列/请求
在服务器端,发送消息给 / user / {username} / queue / requests with convertAndSendToUser(request.getFromUser(),“/ queue / requests”, 请求)和Spring处理其余部分。