我想知道是否有一种方法将EventMachine反应器集成到Rails中? 我该把初始化代码放在哪里? 这是正确的实现方式吗?
我看到了这个示例,它退回到Sinatra进行EventMachine
GET
请求,但这不是我要找的东西。感谢任何形式的帮助。
GET
请求,但这不是我要找的东西。由于Eventmachine是一个持久性运行循环,会永久地阻塞其中一个Rails进程,因此您无法在Rails内部运行Eventmachine引擎。通常的做法是使用一个侧面进程来使用Eventmachine,而Rails通过套接字与其通信以发送通知。
Juggernaut 是这种实现的一个示例,它实现了一个Websocket客户端和一个Rails钩子来向其发送通知。该项目已经弃用了Ruby版本,转而使用JavaScript Node.js版本,但仍然是如何使用Eventmachine的非常全面的示例。
EM.next_tick do
EM.add_periodic_timer(20) do
puts 'from Event Machine in rails code'
end
end
不会阻塞Rails进程应用程序。
不知道这是否符合您的需求。但如果您想提供某种套接字消息系统。
可以看看 Faye。它为Node.js和Rack提供了消息服务器。还有一个由Ryan Bates制作的rails cast,应该可以简化实现过程。
希望能帮到您。
我建议你考虑使用Cramp。它是一个基于EventMachine构建的异步框架,支持Thin服务器:
支持Rack中间件和Rainbows!以及Thin web服务器
如果可以的话,您最好不要再使用EM,因为它似乎已经不再维护了 - 如果遇到错误 - 您将自行解决。
由于https://github.com/eventmachine/eventmachine/issues/479,上面大多数答案在JRuby中都无法正常工作 - 即模式:
Thread.new{ EM.run }
EM::Synchrony
被许多互联网上的答案(例如EventMachine and Ruby Threads - what's really going on here?)所使用,但在JRuby eventmachine实现下是有问题的(在jruby中,纤维是线程,并且目前没有时间表来改变这一点)。
JRuby消息选项将会是
lib
目录下(例如/lib/listener/init.rb
),并创建一个运行EM的类方法,例如Listener.run
。#!/usr/bin/env ruby
require File.expand_path('../../config/environment', File.dirname(__FILE__))
class Listener
def self.run
# your code here
# you can access your models too
end
end
之后我使用了dante gem。创建/init/listener
文件。代码可能如下:
#!/usr/bin/env ruby
require File.expand_path('../../lib/listener/init.rb', __FILE__)
log_file = File.expand_path('../../log/listener.stdout.log', __FILE__)
pid_file = File.expand_path('../../tmp/listener.pid', __FILE__)
listener = Dante::Runner.new('listener')
if ARGV[0] === 'start'
listener.execute(daemonize: true,
pid_path: pid_file,
log_path: log_file) { Listener.run }
elsif ARGV[0] === 'restart'
listener.execute(daemonize: true,
restart: true,
pid_path: pid_file,
log_path: log_file) { Listener.run }
elsif ARGV[0] === 'stop'
listener.execute(kill: true, pid_path: pid_file)
end
现在您可以这样运行您的代码:./bin/listener start
、./bin/listener restart
、./bin/listener stop
您可以使用 god 监控您的监听器是否正在运行。但请确保您使用相同的 pid 文件(/tmp/listener.pid
)。