我正在尝试做什么: 能够让用户订阅许多不同的“聊天室”,并使用反向AJAX / comet将聊天室中的消息发送给登录该房间的所有人。 (有点复杂,但这是一个类似的用例)。
我在做什么: 使用Grails与JMS和Atmosphere。当发送消息时,我正在使用JMS发送由Grails服务接收的消息对象,然后将其广播到大气URL(即大气/消息)。
显然JMS在那里有点多余,但我可以用它来帮助我过滤谁应该检索消息,虽然这看起来并不真实(因为订阅者基本上是单身服务... )。
无论如何,我需要做的只是向正在听大气/消息的人群发送消息。一个RESTful类型的URL在这里将是完美的(即氛围/消息/ *,其中*是房间ID)但是我不知道如何使用Atmosphere。
关于如何实现我想要的任何想法/建议?没有什么是具体的,所以随意提出几乎任何建议。我甚至一直在思考(基于对另一个问题的回答),例如,如果我可以做一些事情,比如向Node.js服务器发送消息并让它处理反向AJAX / comet部分。
答案 0 :(得分:5)
如果我正确理解您的要求,则以下内容应该有效(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 list和Jeanfrancois Arcand's blog。
希望有所帮助。
答案 1 :(得分:2)
彗星的概念存在误解。它只是另一个发布/订阅实现。如果您有多个聊天室,那么您需要有多个“主题”,即用户可以注册的多个频道。例如:
broadcaster['/atmosphere/chatRoom1'].broadcast('Hello world!')
broadcaster['/atmosphere/chatRoom2'].broadcast('Hello world!')
所以我会提前你创建多个频道并且不要手动过滤那些应该检索消息的用户集(这绝对不是它应该做的方式)。您无需在服务器端创建任何内容,因为用户只需注册特定频道并接收消息,任何人都会将消息放入其中。
答案 2 :(得分:0)
我建议您为一个URL创建AtmosphereHandler,例如/ atmosphere / chat-room,然后使用AtmosphereResource并将BroadcastFilter与它绑定,假设将其命名为ChatRoomBroadcastFilter。
每当用户订阅新聊天室时,都会向服务器(从客户端)发送一条消息,告知服务器有关订阅的信息。订阅后,维护用户列表&lt;&gt;聊天室绑定服务器上的某个地方。
每当广播一条消息时,用聊天室ID将其广播。 ChatRoomBroadcastFilter(您可能需要将其设置为PerRequestBroacastFilter)仅在用户订阅聊天室时才将消息传播给用户。我不确定这是否清除了它。如果您需要代码示例,请在评论中提及。我会说,但这需要一些时间,所以现在不能正确;)。