使用 EventMachine 的 Rails 应用程序是不是可以进行长轮询?

Posted

技术标签:

【中文标题】使用 EventMachine 的 Rails 应用程序是不是可以进行长轮询?【英文标题】:Is long polling possible with a Rails application using EventMachine?使用 EventMachine 的 Rails 应用程序是否可以进行长轮询? 【发布时间】:2012-01-03 18:56:12 【问题描述】:

我正在 Rails 3.1 中编写一个简单的聊天室应用程序 - 用于学习目的。 对于初学者,我拥有所有需要的模型(消息、用户、房间等),而且一切都很好。 客户端每分钟轮询一次服务器(例如),如果有新消息,则获取新消息。

我想将简单轮询更改为长轮询,但不知道这是否可以在同一个应用程序中完成,或者我是否必须为长轮询创建一些其他推送服务器。

我阅读了很多有关 EventMachine 的内容,并将我的 rails 应用程序更改为使用它,因为我想将 EventMachine 用于事件驱动机制。我认为 EventMachine 频道会为此派上用场。 客户端会在聊天室中连接并等待消息,并且只有在消息被发送到聊天室时才会收到消息。

我不知道如何在所有客户端连接之间共享 EventMachine::Channel 实例。 这种方法是否可行,还是我走错了路?

如果可能的话,我想要一个可以作为托管在 Heroku 上的单个 Rails 应用程序运行的解决方案。

【问题讨论】:

我不是事件机器方面的专家,但我认为这是可能的。而且您不会在客户端之间共享通道,但每个客户端都有一个通道,并且您需要在 EM 之上构建一些东西以在不同用户之间发送消息。 是的,假设我为每个客户都有一个频道。我在哪里可以存储所有这些通道实例,以便可以从其他人发送消息时调用的控制器访问它? 【参考方案1】:

是的,当然。我刚刚使用事件机编写了一个演示。我的情况是玩家在地图上走来走去,其他玩家应该能够看到它。 演示如下:

    客户端建立连接,报告自己的坐标(随机生成)

    有一个数组保存了每个客户端的所有坐标

    当客户端移动时,它会将其新坐标发送到服务器。然后服务器找到他附近的人(从数组中),并将新坐标推送给这些客户端。

我对近 5000 个客户进行了测试,每秒有 20-30 名玩家移动它的位置。并且服务器进程只占用不到 100M 的内存和 50%-60% 的 cpu 使用率(在单核上)。

在你的情况下,我想你也应该试试 faye。它基于事件机器,是聊天室等事物的适当解决方案。

【讨论】:

【参考方案2】:

扩展我在评论中提到的内容,查看此 blog 帖子,该帖子解释了如何使用 EM 创建基于文本的聊天应用程序,并使用 AMQP 将消息广播给其他用户。

我认为您可能也可以这样做或使用内存队列中的一些来共享消息,这绝对应该在 heroku 上工作,因为您不依赖于外部服务,例如 RabbitMQ。 这是关于不同队列框架的一个很好的讨论:ActiveMQ or RabbitMQ or ZeroMQ or

【讨论】:

【参考方案3】:

Rails 将在版本 4 中添加流式传输。 现在,您可以像this 示例中那样使用 Sinatra 和 Redis 的 Pub/Sub 功能作为后端进行流式传输(长轮询)。您必须添加另一个操作来处​​理用户发送的消息,使用 PUBLISH 命令将它们添加到 Redis 中。你应该使用像 Thin 或 Puma 这样的事件服务器。

【讨论】:

以上是关于使用 EventMachine 的 Rails 应用程序是不是可以进行长轮询?的主要内容,如果未能解决你的问题,请参考以下文章

Rails eventmachine 未初始化 evma_install_oneshot_timer

Ruby on Rails Eventmachine 段错误

Rails - 无法运行应用程序:无法加载 EventMachine C 扩展;

安装eventmachine(1.0.3)时出错[重复]

无法加载 EventMachine C 扩展;使用纯红宝石反应器

Rails、redis 和 node.js 如何异步处理请求?