当前位置: 首页 > 知识库问答 >
问题:

在Spring Websocket上向特定用户发送消息

唐阳晖
2023-03-14

如何仅将websocket消息从服务器发送给特定用户?

我的webapp具有Spring Security设置,并使用websocket。我在尝试只从服务器向特定用户发送消息时遇到了一个棘手的问题。

从阅读手册中我的理解是从服务器上我们可以做到的

simpMessagingTemplate.convertAndSend("/user/{username}/reply", reply);

在客户端:

stompClient.subscribe('/user/reply', handler);

但是我永远无法调用订阅回调。我尝试了许多不同的道路,但没有运气。

如果我将它发送到/topic/reply,它会工作,但所有其他连接的用户也会收到它。

为了说明这个问题,我在github上创建了这个小项目:https://github.com/gerrytan/wsproblem

复制步骤:

1)克隆并构建项目(确保您使用的是jdk 1.7和maven 3.1)

$ git clone https://github.com/gerrytan/wsproblem.git
$ cd wsproblem
$ mvn jetty:run

2) 导航到http://localhost:8080,使用bob/test或jim/test登录

3) 单击“请求用户特定消息”。预期:仅此用户的“Received message to Me Only”旁边显示消息“hello{username}”,实际:未收到任何消息

共有3个答案

单于淇
2023-03-14

我还使用STOMP创建了一个示例websocket项目。我注意到的是

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/topic", "/queue");// including /user also works
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/getfeeds").withSockJS();
}

}

无论配置中是否包含“/user”,它都有效。enableSimpleBroker(。。。

蔺敏达
2023-03-14

啊我发现了我的问题所在。首先,我没有在简单代理上注册/user前缀

<websocket:simple-broker prefix="/topic,/user" />

发送时,我不需要额外的/user前缀:

convertAndSendToUser(principal.getName(), "/reply", reply);

Spring将自动在“/user/”主体前面加上前缀。getName()到目标,因此它解析为“/user/bob/reply”。

这也意味着在javascript中,我必须为每个用户订阅不同的地址

stompClient.subscribe('/user/' + userName + '/reply,...) 
印晋
2023-03-14

哦,客户端不需要知道当前用户的情况,服务器会为您这样做。

在服务器端,使用以下方式向用户发送消息:

simpMessagingTemplate.convertAndSendToUser(username, "/queue/reply", message);

注意:使用队列,而不是主题,Spring总是将队列发送程序

在客户端

stompClient.subscribe("/user/queue/reply", handler);

解释

当任何websocket连接打开时,Spring将为其分配一个会话id(不是HttpSession,为每个连接分配)。当您的客户端订阅以/user/开头的频道时,例如:/user/queue/reply,您的服务器实例将订阅名为queue/reply user[session id]

当使用send message to user时,例如:username是admin,您将编写SimpMessageTemplate。convertAndSendToUser(“管理”,“队列/回复”,消息)

Spring将确定哪个会话id映射到用户admin。例如:它找到了两个会话wsxedc123thnumjm456,Spring将把它翻译成两个目的地queue/reply-userwsxedc123queue/reply-userthnumjm456,并将您的消息发送到您的消息代理。

消息代理接收消息并将其提供回与每个会话相对应的保持会话的服务器实例(WebSocket会话可以由一个或多个服务器保持)。Spring将消息翻译为目的地(例如:user/队列/回复)和会话id(例如:wsxedc123)。然后,它将消息发送到相应的WebSocket会话

 类似资料:
  • 问题内容: 如何仅从服务器向特定用户发送websocket消息? 我的webapp具有spring安全设置,并使用websocket。我在尝试仅从服务器向特定用户发送消息时遇到棘手的问题。 通过阅读手册,我的理解是来自我们可以做的服务器 在客户端: 但是我永远无法调用订阅回调。我尝试了许多不同的方法,但是没有运气。 如果我将其发送到/ topic / reply,它可以工作,但所有其他已连接用户也

  • 我是新手。NET(C#)和WebSocket。。。我已经安装了VS2012和Windows Server 2012,并且已经启动并运行了WebSocket。我似乎无法从一个套接字接收消息并将其发送到另一个特定的套接字。唯一的选择似乎是向所有套接字广播消息。有没有一种方法可以将消息只发送给特定的用户?我希望聊天室主持人有机会拒绝不适当的帖子。

  • 我使用本教程中描述的spring设置了一个WebSocket:https://spring.io/guides/gs/messaging-stomp-websocket/。我需要的是我的服务器每5秒向特定用户发出一条消息。所以我首先做了这个: 而且起作用了。现在,为了只向特定用户发送消息,我更改了以下内容: 在WebSocketConfig.java中添加队列: 更改GreetingControl

  • 假设我在MongoDB中有以下模式: 每个帖子必须有一个所有者,并且可能有许多贡献者(由所有者添加)。 当所有者或任何贡献者对post对象进行更改时,我需要将该更改实时通知给所有相关的用户(使用Socket。IO)。 但是我对如何做到这一点有一些疑问...我的意思是,我知道 Socket.IO 有一些方法可以向特定用户发出消息,但我们需要知道 SocketID。如何将用户 ID 与套接字 ID 相

  • 我正在阅读websockets,在阅读了大量的教程和博客(主要是关于创建一个简单的聊天应用程序)之后,仍然有一个问题没有得到回答: 那么,是否不可能让一些外部应用程序或事件调用一些脚本(bash或php)来使用现有运行的websocket实例向一个或多个连接的浏览器(websocket客户端)发送/广播一些信息(文本)? 抱歉,如果这是一个愚蠢的问题,但我无法找到答案,通过阅读这些博客在网上。 谢

  • 我使用Spring的STOMP over WebSocket实现与一个全功能的ActiveMQ代理。当用户向主题订阅时,在成功订阅之前必须通过一些权限逻辑。我使用ChannelInterceptor应用权限逻辑,如下所示: WebSocketConfig。爪哇: WebSocketSecurityConfig.java: MySubscriptionInterceptor。爪哇: 当没有足够权限的