我正在尝试做的事情:
能够让用户订阅多个不同的“聊天室”,并使用反向 AJAX/comet 将消息从聊天室发送给登录到该房间的每个人。 (有点复杂,但这是一个类似的用例)。
我在做什么:
将 Grails 与 JMS 和 Atmosphere 结合使用。发送消息时,我使用 JMS 发送消息对象,该对象由 Grails 服务接收,然后广播到气氛 URL(即气氛/消息)。
显然,JMS 在那里有点多余,但我虽然可以用它来帮助我过滤谁应该检索消息,尽管这看起来并不真正有效(假设订阅者基本上是单例服务......)。
无论如何,我需要做的只是向收听气氛/消息的正确子集的人发送消息。 RESTful 类型的 URL 在这里是完美的(即,atmosphere/messages/*,其中 * 是房间 ID),但是我不知道如何使用 Atmosphere 来做到这一点。
关于如何实现我想要的目标有什么想法/建议吗?这里没有什么是具体的,所以请随意提出几乎任何建议。我什至一直在思考(基于对另一个问题的回答),例如,我是否可以做一些事情,比如向 Node.js 服务器发送消息,并让它处理反向 AJAX/comet 部分。
What I'm trying to do:
Be able to have users subscribed to a number of different 'chat rooms' and use reverse AJAX / comet to send messages from a chat room to everyone logged into that room. (a bit more complicated but this is a similar use case).
What I'm doing:
Using Grails with JMS and Atmosphere. When a message is sent, I'm using JMS to send the message object which is received by a Grails service which is then broadcasted to the atmosphere URL (i.e. atmosphere/messages).
Obviously JMS is a bit redundant there but I though I could use it to help me filter who should retrieve the message although that doesn't really look it'll work (given that the subscriber is basically a singleton service...).
Anyway, what I need to be able to do is only send out a message to the correct subset of people listening to atmosphere/messages. A RESTful-type URL will be perfect here (i.e. atmosphere/messages/* where * is the room ID) however I have no idea how to do that with Atmosphere.
Any ideas / suggestions on how I can achieve what I want? Nothing is concrete at all here so feel free to suggest almost anything. I've even been thinking (based on the response to another question), for example, if I could do something like send out messages to a Node.js server and have that handle the reverse AJAX / comet part.
发布评论
评论(3)
如果我正确理解您的要求,以下应该可以工作(jax-rs + scala 代码):
1)每个想要从聊天室获取消息的人都注册它:
2)要为所有注册用户广播消息,请调用以下命令方法:
我还建议阅读atmosphere 白皮书,看看邮件列表 和 Jeanfrancois Arcand 的博客。
希望有帮助。
If I understand your requirements correctly the following should work (jax-rs + scala code):
1) Everyone who wants to get messages from a chat room registers for it:
2) To broadcast a message for all the registered users, call the following method:
I also recommend reading the atmosphere whitepaper, have a look at the mailing list and at Jeanfrancois Arcand's blog.
Hope that helps.
人们对彗星的概念存在误解。它只是另一个发布/订阅实现。如果您有多个聊天室,那么您需要有多个“主题”,即用户可以注册的多个频道。例如:
所以我建议您创建多个通道,并且不要手动过滤应该检索消息的用户集(这绝对不是应该这样做的方式)。您不需要在服务器端创建任何内容,因为用户只需注册特定频道并接收任何人放入其中的消息。
There is a misunderstaning of the concept of comet. Its just another publish/subscribe implementation. If you have multiple chat-rooms, then you need to have multiple "topics", i.e. multiple channels the user can register to. E.g.:
So I would advance you to creaet multiple channels and do not filter manually the set of users, which should retrieve messages (which is definitely not the way it should be done). You do not need to create anything on the server side on this, since the user will just register for a specific channel and receive messages, which anyone is putting into it.
我建议您为一个 URL(如 /atmosphere/chat-room)创建一个 AtmosphereHandler,然后使用 AtmosphereResource 并与其绑定一个 BroadcastFilter,假设将其命名为 ChatRoomBroadcastFilter。
每当用户订阅新的聊天室时,就会向服务器发送一条消息(从客户端),告诉服务器有关订阅的信息。订阅后,维护用户列表>>聊天室绑定在服务器上的某个位置。
每当广播消息时,都将其与聊天室 ID 一起广播。仅当用户订阅了聊天室时,ChatRoomBroadcastFilter 中的(您可能需要将其设为 PerRequestBroacastFilter)才将消息传播给用户。我不确定这是否可以解决问题。如果您需要代码示例,请在评论中提及。我会把它放出来,但这需要一些时间,所以现在不放它;)。
I would recommend you create an AtmosphereHandler for one URL like /atmosphere/chat-room and then use the AtmosphereResource and bind an BroadcastFilter with it, lets say name it ChatRoomBroadcastFilter.
Whenever a user subscribes to a new chat room, a message would be sent to the server (from the client) telling the server about the subscription. Once subscribed, maintain the list of users <> chat room bindings somewhere on the server.
Whenever a message is broadcasted, broadcast it with the chat room id with it. The in the ChatRoomBroadcastFilter (You probably need to make this a PerRequestBroacastFilter) propagate the message to the user only if the user subscribed to the chat room. I am not sure if this clears it out. If you need code example please mention in the comments. I'll put that but that needs some time so ain't putting it right now ;).