流媒体播放速度很慢或根本没有流媒体播放

时间:2012-07-27 15:16:03

标签: ruby streaming sinatra thin

我写了一个小脚本,用Sinatra和Thin:

来流式传输每个字节的文件
#!/usr/bin/env ruby

require 'sinatra'
require "sinatra/streaming"

get '/' do
  stream do |out|
    File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd|
      fd.each_byte do |byte|
        break if out.closed?
        putc byte.chr
        out << byte.chr unless out.closed?
      end
    end
  end
end

这可以按预期工作:

% ruby streamer.rb
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop


% curl http://127.0.0.1:4567

并且文件内容双面写入stdout

如果我删除了行putc byte.chr,那么服务器崩溃并被kill -9

杀死

如果我将此脚本更改为模块化样式并添加config.ru,则会出现另一个意外行为:

#!/usr/bin/env ruby

require 'sinatra/base'
require "sinatra/streaming"

class TestStreamer < Sinatra::Base
  helpers Sinatra::Streaming

  get '/' do
    stream do |out|
      File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd|
        fd.each_byte do |byte|
          break if out.closed?
#          putc byte.chr
          out << byte.chr unless out.closed?
        end
      end
    end
  end
end

config.ru:

$:.unshift(File.join(File.dirname(__FILE__)))

require 'rubygems'
require 'sinatra/base'
require 'streamer_modular'

map '/' do
  run TestStreamer
end

启动:

% thin start
>> Using rack adapter
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:3000, CTRL+C to stop

但是当我正在做一个请求时,文件的发送速度非常慢,并在30秒后关闭。在这种情况下,Sinatra不会崩溃。

% time curl -v http://127.0.0.1:3000
* About to connect() to 127.0.0.1 port 3000 (#0)
*   Trying 127.0.0.1... connected
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) libcurl/7.21.0 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
> Host: 127.0.0.1:3000
> Accept: */*
> 
< HTTP/1.1 200 OK
< X-Frame-Options: sameorigin
< X-XSS-Protection: 1; mode=block
< Content-Type: text/html;charset=utf-8
< Connection: close
< Server: thin 1.4.1 codename Chromeo
< 
* Closing connection #0
This package was cre
curl -v http://127.0.0.1:3000  0,01s user 0,00s system 0% cpu 32,559 total

当我删除stream-helper时,文件会在服务器端写入stdout而不会有任何延迟:

#!/usr/bin/env ruby

require 'sinatra/base'
require "sinatra/streaming"

class TestStreamer < Sinatra::Base
  helpers Sinatra::Streaming

  get '/' do
#    stream do |out|
    begin
      File.open("/usr/share/doc/ia32-libs/copyright", "r") do |fd|
        fd.each_byte do |byte|
        #  break if out.closed?
          putc byte.chr
        #  out << byte.chr unless out.closed?
        end
      end
    end
  end
end

% ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]

% gem list

*** LOCAL GEMS ***

backports (2.6.2)
bundler (1.1.5, 1.1.3)
daemons (1.1.8)
eventmachine (0.12.10)
rack (1.4.1)
rack-protection (1.2.0)
rack-test (0.6.1)
sinatra (1.3.2)
sinatra-contrib (1.3.1)
thin (1.4.1)
tilt (1.3.3)

% gem update
Updating installed gems
Nothing to update

% ls -al /usr/share/doc/ia32-libs/copyright
-rw-r--r-- 1 root root 607403  2. Jan 2012  /usr/share/doc/ia32-libs/copyright

% head -n2 /usr/share/doc/ia32-libs/copyright
This package was created by Daniel Jacobowitz <dan@debian.org> on Sun, Aug
8th, 2004.  It was based on the ia32-libs package by Bdale Garbee

我错过了什么吗?你可以重现这个并且可能为我找到一个解决方法吗?

1 个答案:

答案 0 :(得分:1)

在这种模式下,瘦字节的流式字节效率有点低,因为由于Thin基于EventMachine而需要大量的调度和延迟(因此Mike对流式传输的评论不适用于Thin,Mike可能有一个Rails背景在Thin上的这种流式传输确实不起作用。)

但是,Thin(以及任何Rack服务器)应该能够直接流式传输文件:

get '/' do
  File.open("/usr/share/doc/ia32-libs/copyright", "r")
end