xechat icon indicating copy to clipboard operation
xechat copied to clipboard

订阅一对一消息通道的疑问

Open cccy0 opened this issue 3 years ago • 1 comments

我测试了一下前端订阅是可以不用加uid的, 比如这样 stompClient.subscribe('/user/chat', function (data) {xxx}), 然后你写的是这样的 stompClient.subscribe('/user/' + uid + '/chat', function (data) {xxx}), 虽然两者都可以实现需求, 但是后者的原理我不太清楚, 方便解释一下吗.

(ps: 我参考的相关文章: https://juejin.cn/post/6844903661231947784 )

cccy0 avatar Aug 09 '21 03:08 cccy0

我这边是通过 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);
	}

anlingyi avatar Aug 09 '21 12:08 anlingyi