【问题标题】:How To Run EventMachine and Serve Pages In Sinatra?如何在 Sinatra 中运行 EventMachine 和服务页面?
【发布时间】:2013-12-17 19:15:22
【问题描述】:

我正在构建一个使用 TweetStream(使用 EventMachine 侦听推文)的 Sinatra 应用程序。我还希望该应用能够像普通 Sinatra 应用一样提供页面,但 Sinatra 在“监听”推文时似乎无法“监听”页面请求。

我可以通过使用不同的服务器或以不同的方式构建我的应用程序来解决这个问题吗?我尝试过使用 WebBrick 和 Thin。

这基本上是我正在做的事情:

class App < Sinatra::Base

  # listening for tweets
  @client = TweetStream::Client.new
  @client.track(terms) do |status|
    # do some stuff when I detect terms
  end  

  get '/' do
    "Here's some page content!"
  end

end

【问题讨论】:

    标签: ruby sinatra eventmachine tweetstream


    【解决方案1】:

    您可以在 eventmachine 中安装 Sinatra 应用程序(为您提供支持 EM 的网络服务器,即 Thin)。然后,您应该可以从您的 Sinatra 应用程序中完全访问 EM 反应器循环,并允许任何其他 EM 插件也可以运行。

    Sinatra 食谱就是一个很好的例子:

    http://recipes.sinatrarb.com/p/embed/event-machine

    这是一个非常精简的代码版本:

    require 'eventmachine'
    require 'sinatra/base'
    require 'thin'
    
    def run(opts)
    
      EM.run do
        server  = opts[:server] || 'thin'
        host    = opts[:host]   || '0.0.0.0'
        port    = opts[:port]   || '8181'
        web_app = opts[:app]
    
        dispatch = Rack::Builder.app do
          map '/' do
            run web_app
          end
        end
    
        unless ['thin', 'hatetepe', 'goliath'].include? server
          raise "Need an EM webserver, but #{server} isn't"
        end
    
        Rack::Server.start({
          app:    dispatch,
          server: server,
          Host:   host,
          Port:   port
        })
      end
    end
    
    class HelloApp < Sinatra::Base
    
      configure do
        set :threaded, false
      end
    
      get '/hello' do
        'Hello World'
      end
    
      get '/delayed-hello' do
        EM.defer do
          sleep 5
        end
        'I\'m doing work in the background, but I am still free to take requests'
      end
    end
    
    run app: HelloApp.new
    

    【讨论】:

    • 是否需要使用 EM.defer 才能完成这项工作?我正在使用一个使用 EventMachine 的库,所以如果是这种情况,我可能需要对库或我的实现方式进行一些调整。另外,如果我将 EM 块放在 Sinatra 的 get 块之外会发生什么?我希望在应用启动后立即启动 TweetStream。
    【解决方案2】:

    如果您真的想使用推文流式传输功能,那么您需要将流式传输部分作为一个单独的进程运行并将其结果写入数据库,然后从您的 sinatra 应用程序中读取这些记录。

    这就是它的工作原理,twitter 流监听器与你的 sinatra 应用程序是分开的,你需要某种队列来加入它们,比如 redis 或 db,或者类似的东西。

    【讨论】:

    • 这是我想出的一种解决方案。有一个单独的 TweetStream 应用程序,然后是另一个从数据库读取并运行站点的应用程序。我只是希望将这两个东西包含在同一个代码库/应用程序中,因为这是一个相当小的应用程序。
    猜你喜欢
    • 2011-08-29
    • 2021-12-25
    • 2013-07-31
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2012-12-06
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多