1

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

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

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

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

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

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

4

1 回答 1

1

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

https://gist.github.com/f4d997c3eeb6bdc5a9f3

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

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

  • 每次迭代都必须向 Connection 发送一些数据,或者使用next_tick
  • 数据可以重复写入Connection,直到outbound buffer满(根据get_outbound_data_size
  • 一旦文件被完全读取,它应该被关闭(当然)

事实上,在我看来你最好不要使用 FileStreamer,除非你的文件能很好地适应内存。

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

于 2012-01-06T02:31:17.110 回答