从Sinatra路线访问EventMachine频道

时间:2012-12-28 19:51:01

标签: ruby websocket sinatra eventmachine

我在EventMachine上运行了一个简单的Sinatra应用程序,如this example

应用程序正在运行,现在我想允许我在Sinatra中定义的路由使用创建的EventMachine通道访问websocket。我天真地尝试了以下内容,但当然在Sinatra App中,@channel变量没有定义,所以这不起作用。

require 'em-websocket'
require 'sinatra'

EventMachine.run do
  @channel = EM::Channel.new

  class App < Sinatra::Base
    get '/' do
      erb :index
    end

    post '/test' do
      @channel.push "Post request hit endpoint"
      status 200
    end
  end


  EventMachine::WebSocket.start :host => '0.0.0.0', :port => 8080 do |socket|
    socket.onopen do
      sid = @channel.subscribe { |msg| socket.send msg }
      @channel.push "Subscriber ID #{sid} connected!"

      socket.onmessage do |msg|
        @channel.push "Subscriber <#{sid}> sent message: #{msg}"
      end

      socket.onclose do
        @channel.unsubscribe(sid)
      end
    end
  end

  App.run! :port => 3000
end

我怎样才能访问我在Sinatra应用程序中打开的EventMachine频道?

1 个答案:

答案 0 :(得分:3)

如果其他人不知道我们在评论中谈论的内容,这里是一个以我建议的方式使用类实例变量的示例。这会运行,但我不知道它是否符合预期:

require 'em-websocket'
require 'sinatra'
require 'haml'

module Example

  def self.em_channel
    @em_channel ||= EM::Channel.new
  end

  EventMachine.run do

    class App < Sinatra::Base
      configure do
        enable :inline_templates
      end

      get '/' do
        haml :index
      end

      get '/test' do
        Example.em_channel.push "Test request hit endpoint"
        status 200
      end
    end


    EventMachine::WebSocket.start :host => '0.0.0.0', :port => 8080 do |socket|
      socket.onopen do
        sid = Example.em_channel.subscribe { |msg| socket.send msg }
        Example.em_channel.push "Subscriber ID #{sid} connected!"

        socket.onmessage do |msg|
          Example.em_channel.push "Subscriber <#{sid}> sent message: #{msg}"
        end

        socket.onclose do
          Example.em_channel.unsubscribe(sid)
        end
      end
    end

    App.run!
  end
end

__END__

@@ layout
%html
  = yield

@@ index
%div.title Hello world.