2012-11-23 22 views
5

我從插座讀取2部分的問題以及它是如何在Ruby的服務器,比如麒麟或雜種管理如何從一個紅寶石TCPSERVER插槽讀取使用讀,readpartial和read_nonblock

  1. 我學到從套接字中讀取與讀取文件不同,並且沒有發送明確的EOF消息,數據層出不窮。那麼你怎麼知道什麼時候停止閱讀?例如我的TCPServer在這種情況下,當我通過從瀏覽器訪問http://localhost:9799來打我的服務器時,它在沒有更多數據要讀取並且不會拋出EOFError的情況下掛起。
 

require 'socket' 

READ_CHUNK = 1024 
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM) 
addr = Socket.pack_sockaddr_in(9799, '127.0.0.1') 
socket.bind(addr) 
socket.listen(Socket::SOMAXCONN) 
socket.setsockopt(:SOCKET, :REUSEADDR, true) 

puts "Server is listening on port = 9799" 
loop do 
    connection, addr_info = socket.accept 
    data_buffer = "" 

    loop do 
     begin 
      connection.read_nonblock(READ_CHUNK, data_buffer) 
      puts "Buffer = #{data_buffer}" 
     rescue Errno::EAGAIN => e 
      IO.select([connection])   
      retry 
     rescue EOFError 
      break 
     end 
    end 
    connection.write("HTTP/1.1 200 \r\n") 
    connection.write("Content-Type: text/html\r\n") 
    connection.write("Status 200 \r\n") 
    connection.write("Connection: close \r\n") 
    connection.write("Hello World \r\n") 
    connection.close 
end 
 

我想知道什麼是最好的做法/標準方法由紅寶石服務器使用。我看到Unicorn使用kgio庫中的read_nonblock庫和mongrel使用readpartial(我不確定這些但通過代碼,這是我認爲是採用的方法。)即使檢查\ r \ n服務器如何知道輸入完成。 可以解釋這應該怎麼做(我認爲gets不是這種方法 - 它與read,readpartial,​​)。 2)。我真的很感激有幾行關於如何在獨角獸或乘客這樣的服務器上實現這一點

謝謝。

回答

5

它在麒麟這裏 https://github.com/defunkt/unicorn/blob/master/lib/unicorn/http_request.rb#L69-L71

做有add_parse方法(閱讀註釋上述方法) https://github.com/defunkt/unicorn/blob/master/ext/unicorn_http/unicorn_http.rl#L760-L778

也看看這裏的一些說明http://www.ruby-forum.com/topic/2267632#1014288

這裏是你的工作的代碼使用http_parser.rb https://gist.github.com/4136962

gem install http_parser.rb

require 'socket' 
require "http/parser" 


READ_CHUNK = 1024 * 4 
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM) 
addr = Socket.pack_sockaddr_in(9799, '127.0.0.1') 
socket.bind(addr) 
socket.listen(Socket::SOMAXCONN) 
socket.setsockopt(:SOCKET, :REUSEADDR, true) 

puts "Server is listening on port = 9799" 
loop do 
    connection, addr_info = socket.accept 

    parser = Http::Parser.new 
    begin 
     data = connection.readpartial(READ_CHUNK) 
     puts "Buffer = #{data}" 
     parser << data 
    end until parser.headers 

    connection.write("HTTP/1.1 200 \r\n") 
    connection.write("Content-Type: text/html\r\n") 
    connection.write("Status 200 \r\n") 
    connection.write("Connection: close \r\n") 
    connection.write("\r\n\r\n") 
    connection.write("Hello World \r\n") 
    connection.close 
end 
+0

感謝您的回覆並向我介紹http_parser.rb。瞭解任何不使用解析器庫並選擇其他方法的服務器? – Sid

+0

我不知道不使用解析器的服務器,還有什麼樣的另一種方法? – Shtirlic

+0

我很抱歉,我的意思是不使用http_parser.rb庫的服務器。 – Sid