Подтвердить что ты не робот

Как вы создаете EventMachine "внутри" приложения Rails?

У меня есть приложение Rails, и я хочу добавить к нему какую-то поддержку WebSocket. Из разных поисковых запросов, похоже, лучшее решение на основе Ruby на базе WebSocket em-websocket работает в EventMachine.

Мне было интересно, есть ли способ "интегрировать" EventMachine в Rails? Где я могу поставить код инициализации? Правильно ли это удается?

Я видел этот пример, который возвращается на Sinatra для выполнения запроса EventMachine GET, но это не совсем то, что я Я ищу.

Любая помощь приветствуется.

4b9b3361

Ответ 1

Я попробую использовать em-synchrony, чтобы запустить реактор в волокне. В приложении rails вы, вероятно, можете запустить его в инициализаторе, так как кажется, что вы просто хотите покинуть реактор, чтобы отвечать на запросы websocket. Как было предложено в других ответах, я думаю, что вы хотите либо установить связь сокета с вашим реактором, либо использовать один из асинхронных клиентов в хранилище данных, которое и ваш код реакторов и рельсов может считывать и записывать для обмена данными.

Некоторые из моих коллег собрали несколько примеров запуска реактивных реакторов EM по запросу в рубиновом коде для запуска своих тестов в EventMachine. Я бы попытался использовать это как возможный пример; сгребать и тестировать с помощью eventmachine

Ответ 2

Вы не можете запустить движок Eventmachine внутри самого Rails, так как это постоянный цикл цикла, который будет блокировать один из ваших Rails-процессов навсегда. Обычно выполняется боковой процесс, который использует Eventmachine и Rails для связи с ним через сокеты для отправки уведомлений.

Juggernaut служит примером такого рода вещей, когда он реализует клиент Websocket и крючок Rails для отправки ему уведомлений. Проект с тех пор не одобряет версию Ruby в пользу версии JavaScript Node.js, но это все еще служит очень подробным примером того, как можно использовать Eventmachine.

Ответ 3

Если вы запускаете приложение rails на тонком сервере (тонкий запуск пуска exec), то на вашем сервере используется EventMachine, а затем ваше приложение rails может выполнять EM-код везде, где вам нужно.

Пример:

Библиотека o инициализатор с этим кодом:

EM.next_tick do
  EM.add_periodic_timer(20) do
    puts 'from Event Machine in rails code'
  end
end

не блокирует процесс обработки рельсов.

Ответ 4

Не знаю, если это то, что вам нужно. Но если вы хотите предоставить некоторую систему сокетов-сообщений,

Посмотрите Faye. Он предоставляет серверы сообщений для Node.js и Rack. Существует также rails cast для этого Райана Бейтса, который должен упростить реализацию.

Надеюсь, что это поможет.

Ответ 5

Я потратил немало времени на изучение этого. EventMachine нужно запускать как поток в ваших рельсах (если вы не используете Thin), и есть несколько особых соображений для Passenger. Я написал нашу реализацию здесь: http://www.hiringthing.com/2011/11/04/eventmachine-with-rails.html

ОБНОВЛЕНИЕ

Мы вытащили эту конфигурацию в драгоценный камень под названием Momentently. Источник находится здесь https://github.com/eatenbyagrue/momentarily

Ответ 6

Я рассмотрю Cramp. Это асинхронная структура, построенная поверх EventMachine, и поддерживает тонкий сервер:

Поддержка Rack Middlewares + Rainbows! и тонкие веб-серверы

Ответ 7

Вероятно, вам больше не нужно использовать EM, если вы можете помочь ему, кажется, больше не поддерживаются - если вы столкнулись с ошибкой - вы сами.

Большинство ответов выше не работают в JRuby из-за https://github.com/eventmachine/eventmachine/issues/479 - а именно:

Thread.new{ EM.run }

используемый EM::Synchrony, и различные ответы, найденные в Интернете (например, EventMachine и Ruby Threads - что действительно происходит здесь?) нарушены при реализации события JRuby eventmachine (волокна являются нитями в jruby и в настоящее время нет дорожной карты, когда это изменится).

Параметры обмена сообщениями JRuby будут

Ответ 8

У меня была такая же проблема и найденное решение. Сначала введите код lib dir (например, /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).