xechat
xechat copied to clipboard
订阅一对一消息通道的疑问
我测试了一下前端订阅是可以不用加uid的, 比如这样 stompClient.subscribe('/user/chat', function (data) {xxx}), 然后你写的是这样的 stompClient.subscribe('/user/' + uid + '/chat', function (data) {xxx}), 虽然两者都可以实现需求, 但是后者的原理我不太清楚, 方便解释一下吗.
(ps: 我参考的相关文章: https://juejin.cn/post/6844903661231947784 )
我这边是通过 messagingTemplate.convertAndSendToUser(String user, String destination, Object payload)
方法将消息发送到指定用户的,这个方法会将我传入的userId和地址进行拼接,拼接后的发送地址为:/user/{userId}/chat
,所以客户端订阅的时候需要拼接自己的userId。
发送消息到指定用户的方法
- receiver:userId数组
-
StompConstant.SUB_USER:内容为
/chat
public void sendMessageToUser(String[] receiver, MessageVO messageVO) throws Exception {
if (!CheckUtils.checkReceiver(receiver)) {
throw new ErrorCodeException(CodeEnum.INVALID_PARAMETERS);
}
ResponseVO responseVO = buildResponseVo(messageVO);
for (int i = 0, len = receiver.length; i < len; i++) {
// 将消息发送到指定用户 参数说明:1.消息接收者 2.消息订阅地址 3.消息内容
messagingTemplate.convertAndSendToUser(receiver[i], StompConstant.SUB_USER, responseVO);
}
}
@Override
public void convertAndSendToUser(String user, String destination, Object payload,
@Nullable Map<String, Object> headers, @Nullable MessagePostProcessor postProcessor)
throws MessagingException {
Assert.notNull(user, "User must not be null");
user = StringUtils.replace(user, "/", "%2F");
destination = destination.startsWith("/") ? destination : "/" + destination;
super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor);
}