如何解决WebSocket STOMP 已经覆盖类主体方法 getname() convertAndSendToUser 不起作用
我只想测试 convertAndSendToUser
是否有效。如果您有同样的问题或经历,请帮我解决。
你可以在我使用代码更新的时候看到方法,它一样ok(convertAndSend
)。当我使用 convertAndSendToUser
时,我的 html 无法获取 STOMP 消息。所以我猜目的地是对的,但有什么不对的我找不到;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Resource
private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;
@Autowired
private WebSocketService webSocketService;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint(PathConstant.STOMP_CHAT_CHANNEL).addInterceptors(webSocketHandshakeInterceptor).setAllowedOrigins("*").withSockJS(); registry.addEndpoint(PathConstant.STOMP_CLASS_COMMEND).setAllowedOrigins("*").withSockJS().setInterceptors(webSocketHandshakeInterceptor);
// test
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS().setInterceptors(webSocketHandshakeInterceptor);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker(PathConstant.TOPIC,PathConstant.USER);
registry.setApplicationDestinationPrefixes(PathConstant.APP);
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(new ChannelInterceptor() {
@Override
public Message<?> preSend(Message<?> message,MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message,StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
String token = accessor.getFirstNativeHeader("Auth_token");
String username = webSocketService.checkToken(token).getUser_name();
String uid = UUID.randomUUID().toString().replace("-","");
SocketUser user = new SocketUser(uid,username);
accessor.setUser(user);
webSocketService.addSocketCache(uid,user);
}
return message;
}
});
}
}
public class SocketUser implements Principal,Serializable {
private static final long serialVersionUID = -2882674220040446492L;
private final String username;
private final String userId;
public SocketUser(String userId,String username) {
this.userId = userId;
this.username = username;
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getUsername() {
return username;
}
public String getUserId() {
return userId;
}
@Override
public String getName() {
return userId;
}
}
@RestController
public class ChatroomController {
private final Logger logger = LoggerFactory.getLogger(ChatroomController.class);
@Autowired
private MessageService messageService;
@Autowired
private Gson gson;
@Autowired
ChatroomMessageRepository chatroomMessageRepository;
@Autowired
ChatroomUserRepository chatroomUserRepository;
@Autowired
private SimpMessageSendingOperations messagingTemplate;
// @Autowired
// private SimpMessagingTemplate messagingTemplate;
@Autowired
private SimpUserRegistry userRegistry;
@Autowired
WebSocketService webSocketService;
@MessageMapping(PathConstant.STOMP_CHAT_ADD_USER)
@SendTo(PathConstant.TOPIC_PUBLIC)
public ChatMessage addUser(@Payload ChatMessage chatMessage,StompHeaderAccessor accessor) {
userRegistry.getUsers().stream().forEach(System.out::println);
accessor.getSessionAttributes().put("username",chatMessage.getSender());
chatMessage.setUid(accessor.getUser().getName());
return chatMessage;
}
@MessageMapping(PathConstant.STOMP_CHAT_ADD_MESSAGE)
@SendTo(PathConstant.TOPIC_PUBLIC)
public ChatMessage addMessage(@Payload ChatMessage chatMessage,StompHeaderAccessor accessor) {
return chatMessage;
}
@MessageMapping(PathConstant.USER_CHAT)
public void sendToUser(@Payload ChatMessage chatMessage,StompHeaderAccessor accessor) {
String uid = accessor.getUser().getName();
chatMessage.setType(ChatMessage.MessageType.CHAT);
System.out.println("/user/" + uid + "/chat");
messagingTemplate.convertAndSendToUser(uid,"/user/" + uid + "/chat",chatMessage);
// messagingTemplate.convertAndSend("/user/" + uid + "/chat",chatMessage);
}
}
解决方法
我在关注您的帖子时遇到问题,但我在休息控制器中的处理方式是这样的:
@ApiOperation(
value = "Returns the current SDDF Host/Port the bridge is connected to",produces = "application/json",notes =
"""
# STOMP Enabled
To access this endpoint via a **STOMP** websocket
* Send a message to: `/app/rest/sddf_info`
* Subscribe to: `/user/queue/rest/sddf_info`
"""
)
@GetMapping("/sddf_info")
@MessageMapping("/rest/sddf_info")
@SendToUser
fun getSDDFInfo(): SDDFInfo {
return SDDFInfo(
sddfConfigProperties.hostName,sddfConfigProperties.hostPort
)
}
您可以通过两种方式点击此控制器:
- http 访问
/sddf_info
- 向
/app/rest/sddf_info
发送 STOMP 消息
如果您订阅了 /user/queue/rest/sddf_info
,@SendToUser
会将来自 stomp 传入消息的响应传递到 /app/rest/sddf_info
到该主题
我有一个配置:
@Configuration
@EnableWebSocketMessageBroker
class STOMPWebSocketConfig : WebSocketMessageBrokerConfigurer {
....
override fun configureMessageBroker(config: MessageBrokerRegistry) {
config.enableSimpleBroker("/topic","/queue")
config.setApplicationDestinationPrefixes("/app")
config.setUserDestinationPrefix("/user")
}
这会配置其中一些端点位置..
(同样,这段代码是 Kotlin 而不是 Java - 但 Kotlin 是 100% Java 兼容的......所以如果你正在编写 Java,你应该能够从这里弄清楚)
这是您要问的吗...如何正确使用用户队列 (@SendToUser
)?
- https://www.baeldung.com/spring-websockets-sendtouser
- https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html#websocket-stomp-user-destination
super.convertAndSend(this.destinationPrefix + user + destination,payload,headers,postProcessor); private String destinationPrefix = "/user/"; spring-message 已经把你的 uid 和“user”放在你的目的地,所以你可以像这样使用“messagesTemplate.convertAndSendToUser(uid,"/chat",chatMessage)”
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。