2012-12-28 79 views
3

我有一個在EventMachine上運行的簡單的Sinatra App,如this example從Sinatra路線訪問EventMachine頻道

該應用程序正在運行,現在我想允許我在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頻道?

+0

您是否嘗試過在[配置塊](http://www.sinatrarb.com/intro#Configuration)內部安裝EM?然後你可以通過'settings.channel'訪問它(如果它有效,我只是建議這個,我沒有嘗試過)。 – iain

+0

@inin的問題是,如何在Sinatra之外找到它?我嘗試過的唯一辦法就是將其設置爲一個全局變量,我認爲這是可以的,但是通常會皺起眉頭...... – Andrew

+0

將整個模塊包裝到模塊中並使用模塊的類實例變量如何?它的範圍和全球! :) – iain

回答

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. 
+0

感謝分享此代碼,這是一個很好的解決方案。 – Andrew