如何在“内部”生成一个 EventMachine? Rails 应用程序?
我有一个 Rails 应用程序,并且希望为其添加某种 WebSocket 支持。从各种谷歌搜索来看,最好的基于 Ruby 的 WebSocket 解决方案似乎是在 EventMachine 上运行的 em-websocket。
我想知道是否有一种方法可以将 EventMachine 反应器“集成”到 Rails 中?初始化代码放在哪里?这是实现这一目标的正确方法吗?
我见过 this 示例,它依靠 Sinatra 来执行 EventMachine GET request,但这并不完全是我想要的。
任何帮助表示赞赏。
I've got a Rails application, and am looking to add some sort of WebSocket support to it. From various googling, it appears that the best Ruby based WebSocket solution is em-websocket running on EventMachine.
I was wondering if there was a way to "integrate" an EventMachine reactor into Rails? Where do I put the initialization code? Is this the proper way to accomplish this?
I've seen this example that falls back on Sinatra to do an EventMachine GET
request, but that isn't quite what I'm looking for.
Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您无法在 Rails 本身内部运行 Eventmachine 引擎,因为它是一个持久运行循环,会永久阻塞您的 Rails 进程之一。通常所做的是有一个使用 Eventmachine 的副进程,Rails 通过套接字与其通信以发送通知。
Juggernaut 就是这种情况的一个例子,它实现了一个 Websocket 客户端和一个 Rails 钩子来向其发送通知它。此后,该项目已弃用 Ruby 版本,转而使用 JavaScript Node.js 版本,但这仍然是如何使用 Eventmachine 的一个非常全面的示例。
You cannot run the Eventmachine engine inside of Rails itself as it is a persistent run loop that would block one of your Rails processes permanently. What is usually done is there's a side-process that uses Eventmachine and Rails communicates with it through sockets to send notifications.
Juggernaut serves as an example of this kind of thing where it implements a Websocket client and a Rails hook to send notifications to it. The project has since deprecated the Ruby version in favor of a JavaScript Node.js version but this still serves as a very thorough example of how Eventmachine can be used.
如果您在瘦服务器中运行 Rails 应用程序(bundle exec Thin Start),瘦服务器会为您运行 EventMachine,然后您的 Rails 应用程序可以在您需要的任何地方执行 EM 代码。
例如:
具有该代码的库初始化程序:
不会阻止 Rails 进程应用程序。
If you run rails application in a thin server (bundle exec thin start) thin server run EventMachine for you and then your rails application can execute EM code wherever you need.
By example:
A library o initializer with that code:
not blocks rails processes application.
不知道这是否是你所追求的。但是如果您想提供某种套接字消息系统。
看看 Faye。它为 Node.js 和 Rack 提供消息服务器。 Ryan Bates 还为此提供了 railscast ,这应该可以简化实现。
希望有帮助。
Don't know if this is what you are after. But if you would like to do provide some kind of socket-messaging system.
Have a look at Faye. It provides message servers for Node.js and Rack. There is also a rails cast for this by Ryan Bates which should simplify the implementation.
Hope that helps.
我花了相当多的时间来研究这个问题。 EventMachine 需要在 Rails 安装中作为线程运行(除非您使用 Thin),并且对于 Passenger 有一些特殊的注意事项。我在这里编写了我们的实现:http://www.hiringthing。 com/2011/11/04/eventmachine-with-rails.html
更新
我们将此配置提取到名为 Momentarily 的 gem 中。来源在这里 https://github.com/eatenbyagrue/momentarily
I spent a considerable amount of time looking into this. EventMachine need to run as a thread in your rails install (unless you are using Thin,) and there are some special considerations for Passenger. I wrote our implementation up here: http://www.hiringthing.com/2011/11/04/eventmachine-with-rails.html
UPDATE
We pulled this configuration out into a gem called Momentarily. Source is here https://github.com/eatenbyagrue/momentarily
我尝试使用 em-synchrony 在光纤中启动反应器。在 Rails 应用程序中,您可能可以在初始化程序中启动它,因为听起来您只想让反应器运行以响应 Websocket 请求。正如其他答案所建议的,我认为您想要与您的反应器建立套接字通信,或者使用异步客户端之一来连接您的反应器和 Rails 代码都可以读取和写入以交换数据的数据存储。
我的一些同事整理了一些在 ruby 代码中按需启动 EM 反应器的示例,以便在 EventMachine 中运行测试。我会尝试用它作为一个可能的例子; 使用 eventmachine 进行抓取和测试
I'd try using em-synchrony to start a reactor in a fiber. In a rails app you can probably start it in an initializer since it sounds like you just want to leave the reactor running to respond to websocket requests. As suggested by the other answers I think you want to either setup socket communication with your reactor or use one of the asynchronous clients to a data store which both your reactor and rails code can read from and write to to exchange data.
Some of my coworkers put together some examples of starting EM reactors on demand in ruby code to run their tests within EventMachine. I'd try using that as a possible example; raking and testing with eventmachine
我会考虑研究抽筋。它是一个构建在 EventMachine 之上的异步框架,并且支持瘦服务器:
I'd consider looking into Cramp. It's an async framework built on top of EventMachine, and it supports Thin server:
如果你可以帮助的话,你可能不应该再使用 EM,它似乎不再被维护 - 如果你遇到错误 - 你就得靠自己了。
上面的大多数答案在 JRuby 中不起作用,因为 https://github.com/eventmachine /eventmachine/issues/479 - 即
EM::Synchrony
使用的模式以及在互联网上找到的各种答案(例如 EventMachine 和 Ruby 线程 - 这里到底发生了什么?)在 JRuby eventmachine 实现下被破坏了(纤程是 jruby 中的线程,目前没有关于何时改变的路线图)。
JRuby 消息传递选项将
You probably shouldn't use EM any more if you can help it, it seems to no longer be maintained - if you encounter a bug - you're on your own.
Most of the answers above don't work in JRuby due to https://github.com/eventmachine/eventmachine/issues/479 - namely the pattern:
used by
EM::Synchrony
and various answers found around the internet (such as EventMachine and Ruby Threads - what's really going on here?) are broken under JRuby eventmachine implementation (fibers are threads in jruby and there's currently no roadmap on when this will change).JRuby messaging options would be
我有同样的问题并找到了解决方案。首先,将代码放入
lib
目录(例如/lib/listener/init.rb
)并创建一个运行 EM 的类方法,例如Listener。运行
。之后我使用了 dante gem。创建
/init/listener
文件。代码可能是这样的:现在您可以运行这样的代码:
./bin/listener start
,./bin/listener restart
,./bin /listener stop
您可以使用 god 来监控监听器的运行情况。但请确保您使用相同的 pid 文件 (
/tmp/listener.pid
)。I had same problem and found solution. First, put your code in
lib
dir (for example/lib/listener/init.rb
) and create one class method that run EM, for exampleListener.run
.After that I used dante gem. Create
/init/listener
file. The code may be like that:Now you can run you code like that:
./bin/listener start
,./bin/listener restart
,./bin/listener stop
You can use god for monitoring your listener is running. But make sure you're using same pid file (
/tmp/listener.pid
).