【问题标题】:Broadcasting to a subset of subscribers in Atmosphere向 Atmosphere 中的一部分订阅者广播
【发布时间】:2011-08-26 01:32:34
【问题描述】:

我正在尝试做的事情: 能够让用户订阅多个不同的“聊天室”,并使用反向 AJAX/comet 从聊天室向登录该房间的每个人发送消息。 (有点复杂,但这是一个类似的用例)。

我在做什么: 将 Grails 与 JMS 和 Atmosphere 结合使用。发送消息时,我使用 JMS 发送消息对象,该对象由 Grails 服务接收,然后广播到气氛 URL(即气氛/消息)。

显然 JMS 在那里有点多余,但我虽然可以使用它来帮助我过滤谁应该检索消息,尽管这看起来并不能正常工作(鉴于订阅者基本上是一个单例服务...... )。

无论如何,我需要做的只是向收听气氛/消息的正确子集发送消息。 RESTful 类型的 URL 在这里是完美的(即气氛/消息/*,其中 * 是房间 ID)但是我不知道如何使用 Atmosphere 来做到这一点。

关于如何实现我想要的任何想法/建议?这里没有什么是具体的,所以几乎可以随意提出任何建议。我什至一直在考虑(基于对另一个问题的回答),例如,如果我可以做一些事情,比如向 Node.js 服务器发送消息并让它处理反向 AJAX/comet 部分。

【问题讨论】:

  • 仅供参考:该技术通常称为Comet(相对于reverse-ajax)。

标签: grails comet reverse-ajax atmosphere


【解决方案1】:

如果我正确理解您的要求,以下应该可以工作(jax-rs + scala 代码):

1) 想要从聊天室获取消息的每个人都注册它:

@GET
@Path(choose/a/path)
def register(@QueryParam("chatroomId") chatroomId: Broadcaster) {
  // alternatively, the Suspend annotation can be used
  new SuspendResponse.SuspendResponseBuilder[String]()
          .resumeOnBroadcast(false).broadcaster(chatroomId).scope(SCOPE.REQUEST)
          .period(suspendTimeout, TimeUnit.MINUTES)
          .addListener(new AtmosphereEventsLogger()).build
}

2) 为所有注册用户广播消息,调用如下方法:

@POST
@Broadcast
@Path(choose/a/path/{chatroomId})
def broadcast(@PathParam("chatroomId") id: String) {
  // first find your broadcaster with the BroadcasterFactory
  BroadcasterFactory.getDefault().lookupAll() // or maybe there is a find by id?
  broadcaster = ...
  broadcaster.broadcast(<your message>)
}

我还建议阅读atmosphere whitepaper,看看mailing listJeanfrancois Arcand's blog

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    对彗星的概念存在误解。它只是另一个发布/订阅实现。如果您有多个聊天室,那么您需要有多个“主题”,即用户可以注册的多个频道。例如:

    broadcaster['/atmosphere/chatRoom1'].broadcast('Hello world!')
    
    broadcaster['/atmosphere/chatRoom2'].broadcast('Hello world!')
    

    因此,我建议您创建多个频道,并且不要手动过滤应该检索消息的用户集(这绝对不是应该这样做的方式)。你不需要在服务器端创建任何东西,因为用户只需注册一个特定的频道并接收任何人都在其中的消息。

    【讨论】:

    • 那么这些频道可以动态生成吗?如,我不必为每个频道都有一个句柄?这是服务器上的一种方法,我需要在其中写出客户端订阅该频道将收到的响应。为此,我需要为该频道提供一个处理程序。我可能需要的是能够拥有各种通配符处理程序方法(即以“/atmosphere/chatRoomX”形式提供所有频道,其中 X = 聊天室 id)。
    【解决方案3】:

    我建议您为 /atmosphere/chat-room 之类的 URL 创建一个 AtmosphereHandler,然后使用 AtmosphereResource 并将 BroadcastFilter 与它绑定,假设将其命名为 ChatRoomBroadcastFilter。

    每当用户订阅新的聊天室时,都会(从客户端)向服务器发送一条消息,告知服务器有关订阅的信息。订阅后,维护用户列表服务器上某处的聊天室绑定。

    每当广播消息时,都将其与聊天室 id 一起广播。只有当用户订阅了聊天室时,ChatRoomBroadcastFilter(您可能需要将其设为 PerRequestBroadcastFilter)才将消息传播给用户。我不确定这是否可以清除它。如果您需要代码示例,请在 cmets 中提及。我会说,但这需要一些时间,所以现在不说;)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 2015-09-19
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多