【问题标题】:Streaming files from EventMachine handler?从 EventMachine 处理程序流式传输文件?
【发布时间】:2010-11-09 21:16:27
【问题描述】:

我正在创建一个流式事件机器服务器。我担心避免阻塞 IO 或做任何其他事情来破坏事件循环。

根据我的阅读,ruby 的非阻塞 IO 可用于以非阻塞方式流式传输文件,或者我可以调用 next_tick,但我有点不清楚这些方法中哪种更可取。

部分问题是我没有找到对 ruby​​ 中非阻塞 IO 库函数的很好解释。

短版: 假设一个长期存在的网络 IO 操作,每个文件有几个挂钟分钟的流式传输,那么在 eventmachine 中执行此操作的最佳方法是什么而不会使事件循环变得混乱?

  while 1 do
    file.read do |bytes|
      @conn.send_data bytes
    end
  end

我知道上面的代码会阻塞,我想知道用什么代替它。此外,我不能按原样使用作为 eventmachine 一部分的 FileStreamer 类,因为我需要在读取数据之后但在发送数据之前对其进行操作。

【问题讨论】:

标签: ruby nio eventmachine


【解决方案1】:

我认为您仍然可以使用 FileStreamer。 FileStreamer 期望它的第一个参数是一个连接,但这是一个松散的契约。只要您实现 FileStreamer 期望的方法,它就应该可以工作。看看这个

https://gist.github.com/f4d997c3eeb6bdc5a9f3

您需要处理的方法是send_datasend_file_data。您可以在此处执行您的操作。然后将结果传递给 EM::Connection。

另外,根据我对代码的阅读,FileStreamer 的特殊属性是它分配了一个内存映射文件(除非文件很小)。您可以通过打开常规 Ruby 文件、从中读取块、进行操作以及模拟 FileStreamer.stream_one_chunk 的行为来完成基本相同的操作。基本上是:

  • 每次迭代都必须向连接发送一些数据,或者使用next_tick 重新调度自身
  • 数据可以重复写入连接,直到出站缓冲区已满(根据get_outbound_data_size
  • 文件被完全读取后,应该关闭(当然)

事实上,在我看来,您应该最好不要使用 FileStreamer,除非您的文件可以轻松放入内存中。

您可以查看 EM::Protocols,了解如何在数据流经时对其进行转换。

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多