Можно ли получить доступ к каналам Ruby EventMachine из Thin / Rack / Sinatra? - PullRequest
2 голосов
/ 22 апреля 2011

Я хочу создать простую систему уведомлений RESTful для внутреннего проекта, использующего Sinatra.В прошлом я использовал каналы EventMachine для подписки / публикации событий, но во всех моих предыдущих случаях я использовал EventMachine напрямую.

Кто-нибудь знает, возможно ли создавать, подписываться и публиковать каналы EventMachine(работает в Thin) из приложения Sinatra или даже из какого-либо промежуточного программного обеспечения Rack?

Ответы [ 2 ]

2 голосов
/ 22 апреля 2011

Посмотрите на async_sinatra .

По сути, чтобы можно было использовать EventMachine при работе в Thin, вам нужно знать, что вы хотите обрабатывать запросы асинхронно. Протокол Rack по своей конструкции является синхронным, и Thin ожидает, что запрос будет выполнен, когда обработчик вернется. Есть способы, чтобы Thin осознал, что вы хотите обрабатывать запрос асинхронно (см. think_async для примера), а async_sinatra делает это очень просто.

1 голос
/ 11 августа 2011

Bryan, Вы можете использовать библиотеку em-http-request (https://github.com/igrigorik/em-http-request), это позволит вам ссылаться на конкретное приложение EventMachine, запущенное на A. одном и том же сервере, B. другом сервере или C. везде, где вы хотитедействительно.

require 'eventmachine'
require 'em-http-request'
require 'sinatra/base'
require 'thin'

class ServerClass < EventMachine::Connection
  def initialize(*args)
    # ruby singleton - store channel data in global hash
    ($channels ||= [])
  end

  def post_init
    puts "initialized"
    $cb.call("initialized");
  end

  def receive_data(data)
    # got information from client connection
  end

  def channel_send(msg,channel)
    $channels[channel].send_data(msg)
  end

  def channels_send(msg)
    $channels.each{|channel| channel.send_data(msg)}
  end

  def unbind
    # puts user left
  end

end

EventMachine.run do
  $cb = EM.callback {|msg| puts msg #do something creative}
  $ems = EventMachine::start_server('0.0.0.0',ServerClass,args)

  class App < Sinatra::Base
    set :public, File.dirname(__FILE__) + '/public'

    get '/' do
      erb :index          
    end

  end

  App.run!({:port => 3000})

end

Выше приведен базовый каркас. В зависимости от того, как вы хотите отправлять данные, вы можете использовать WebSockets (em-websocket) и связывать каждого пользователя при входе в систему (необходимо добавить систему входа в систему).), или вы можете использовать это для чего угодно. Пока у вас есть глобальная ссылка на объект Eventmachine (соединение, веб-сокет, канал), вы можете передавать сообщения изнутри вашего приложения.

BTW - это необязательно длядобавьте EventMachine.run do; .... end loop, так как Thin сделает это в любом случае. Это помогает узнать, как это работает.

Удачи

...