我试图通过让客户端订阅一个主题,然后让服务器向该目的地发送一条消息,来发送一条针对特定用户的消息。
在客户端,用户将订阅:/user/{userId}/queue/friend-requests
,在本例中为/user/7/queue/friend-requests
。
在服务器端,我会首先在建立WebSocket连接时将主体名称设置为{userId}
。因此,在连接后,当我在服务器userRegistry.getUsers()
中打印时,我得到了这个打印的[name=[7], sessions={e0a8db6b-90e9-c464-5409-c1ac71560e8d=id=e0a8db6b-90e9-c464-5409-c1ac71560e8d, subscriptions={0=destination=/user/7/queue/friend-requests, 1=destination=/topic}}]
,其中name = [7]
将是用户唯一的userID。
在服务器端,当我向"/app/friend-requests"
发送消息时,它会被这个控制器类成功接收:
@Controller
public class FriendRequestController {
private SessionToken sessionToken;
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@Autowired
private SimpUserRegistry userRegistry;
@Autowired
private FriendRequestService friendRequestService;
@MessageMapping("/friend-requests")
public void sendFriendRequest(@Payload FriendRequest friendRequest, Principal principal) throws InvalidSessionTokenException{
System.out.println(userRegistry.getUsers());
System.out.println(principal.getName());
System.out.println("- - - - - - - - - -");
simpMessagingTemplate.convertAndSendToUser("7", "/queue/friend-requests", "user specific");
simpMessagingTemplate.convertAndSend("/topic", "topic");
System.out.println("- - - - - - - - - -");
但是,当我使用simpMessagingTemplate.convertAndSendToUser(7, "/queue/friend-requests", "user specifiq");
向订阅/user/7/queue/friend-requests
的用户发送消息时,什么也没有发生。客户端不接收消息,并且在服务器内部也不打印任何内容。
这是配置类:
@Configuration
@EnableWebSocketMessageBroker
@ComponentScan(basePackages = {"com/swoosh/springbootchatapp/chatapp/friend/system/stomp/friendrequest/controller"})
public class StompConfig implements WebSocketMessageBrokerConfigurer
{
@Override
public void registerStompEndpoints(StompEndpointRegistry registry){
registry.addEndpoint("/friend-requests").setAllowedOrigins("*").setHandshakeHandler(new StompHandshakeHandler());
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry){
registry.enableSimpleBroker("/queue", "/topic", "/user");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/user");
}
这是客户端的订阅:
String destination = "/user/" + Main.getApplicationState().getUserId() + "/queue/friend-requests";
stompFriendRequestsHandler.getSession().subscribe(destination, new StompFrameHandler() {
@Override
public Type getPayloadType(StompHeaders headers) {
// Return the expected payload type of the message
return String.class;
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
System.out.println("- - - - - - - - - - - - - - - - - - -");
System.out.println("recived the user specifiq");
System.out.println(payload);
}
});
stompFriendRequestsHandler.getSession().subscribe("/topic", new StompFrameHandler() {
@Override
public Type getPayloadType(StompHeaders headers) {
return String.class;
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
System.out.println("- - - - - - - - - - - - - - - - - - -");
System.out.println("recieved the topic");
System.out.println(payload);
}
});
}
有人知道为什么吗。另外,当使用convertAndSendToUser
时,第一个参数是否会用于查找特定WebSocket会话的name
值?
1条答案
按热度按时间polhcujo1#
服务器应该像这样发送:
并且客户端应当订阅
/user/queue/friend-requests
。