3

我有一个在 EventMachine 上运行的简单 Sinatra 应用程序,例如这个示例

该应用程序正在运行,现在我想允许我在 Sinatra 中定义的路由使用创建的 EventMachine 通道访问 websocket。我天真地尝试了以下方法,但当然在 Sinatra 应用程序中,@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 频道?

4

1 回答 1

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.
于 2012-12-30T10:42:33.320 回答