You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring WebSocket STOMP中convertAndSendToUser()无法投递私有消息问题求助

Spring WebSocket STOMP中convertAndSendToUser()无法投递私有消息问题求助

我现在在做Spring WebSocket STOMP的私有消息功能,广播消息完全正常,但用convertAndSendToUser()发的消息就是收不到。客户端订阅了/user/queue/private但从来没收到过消息,下面是我的相关代码和排查情况,麻烦大家帮忙看看问题出在哪?

一、WebSocket配置类

@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig(
    private val userHandshakeInterceptor: UserHandshakeInterceptor,
    private val userHandshakeHandler: UserHandshakeHandler
) : WebSocketMessageBrokerConfigurer {

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
        registry.addEndpoint("/ws/chat")
            .setAllowedOriginPatterns("*")
            .addInterceptors(userHandshakeInterceptor)
            .setHandshakeHandler(userHandshakeHandler)
            .withSockJS()
    }

    override fun configureMessageBroker(registry: MessageBrokerRegistry) {
        registry.enableSimpleBroker("/topic", "/queue", "/user")
        registry.setApplicationDestinationPrefixes("/app")
        registry.setUserDestinationPrefix("/user")
    }
}

二、消息控制器

@MessageMapping("/chat.send")
fun sendChatMessage(
    @Payload message: SenderMessage,
    @Header("simpSessionAttributes") attributes: Map<String, Any>
) {
    val userId = attributes["userId"] as String
    val receiverMessage = ReceiverMessage(message.content, userId)
    simpMessagingTemplate.convertAndSendToUser(
        message.recipient[0],
        "/queue/private",
        receiverMessage
    )
}

三、前端客户端实现(JavaScript)

function connect() {
    const userId = "user-a-id"; // 示例ID
    const socket = new SockJS(`http://localhost:8082/ws/chat?userId=${userId}&to=user-b-id&type=private`);
    stompClient = Stomp.over(socket);
    
    stompClient.connect({}, function() {
        stompClient.subscribe(`/user/${userId}/queue/private`, (message) => {
            console.log("Received private message:", message.body);
        });
    });
}

function sendPrivateMessage() {
    const message = {
        content: "Hello",
        recipient: ["user-b-id"] // 接收方ID
    };
    stompClient.send("/app/chat.send", {}, JSON.stringify(message));
}

四、我已经尝试过的操作

  • 验证了客户端连接时携带的query参数里的userId是正确的
  • 确认握手拦截器已经把userId正确存入了session属性中
  • 把目标地址从/queue/chat改成了/queue/private
  • 显式订阅了/user/${userId}/queue/private这个地址
  • 确认广播消息(用/topic前缀)完全正常
  • 在客户端和服务端都加了详细日志

五、调试信息

  • 服务端日志显示sendChatMessage()方法确实在处理消息
  • 服务端和浏览器控制台都没有报错
  • WebSocket帧显示订阅/user/queue/private的请求是成功的
  • 接收消息的客户端确实用正确的ID连接上了

六、关键疑问

  • 针对用户目标地址,还需要额外的配置吗?
  • 怎么才能查看Spring内部实际使用的目标地址是什么?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:59:31