2012-11-23 37 views
5

Tôi có một câu hỏi 2 phần vào đọc từ ổ cắm và làm thế nào là nó được quản lý trên máy chủ của Ruby như Unicorn hoặc mongrelLàm thế nào để đọc từ một ổ cắm TCPServer trong ruby ​​bằng cách sử dụng đọc, readpartial và read_nonblock

  1. tôi đã học được mà để đọc từ một ổ cắm là khác nhau từ đọc một tập tin và rằng không có thông điệp EOF riêng biệt được gửi và dữ liệu là một dòng vô tận. Vậy làm thế nào để bạn biết khi nào nên ngừng đọc? TCPServer của tôi chẳng hạn trong trường hợp này khi tôi nhấn máy chủ của tôi bằng cách truy cập http://localhost:9799 từ trình duyệt, nó bị treo sau khi không còn dữ liệu nào để đọc và nó cũng sẽ không ném 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 
 

Tôi muốn biết whats thực hành/tiếp cận tiêu chuẩn tốt nhất được sử dụng bởi các máy chủ Ruby. Tôi thấy Unicorn sử dụng read_nonblock từ thư viện kgio và mongrel sử dụng readpartial (tôi không chắc chắn về điều này nhưng đi qua mã này là những gì tôi cảm thấy là cách tiếp cận được thông qua.) Ngay cả với kiểm tra cho \ r \ n làm thế nào để máy chủ biết đầu vào hoàn tất. Có thể giải thích cách thức này nên được thực hiện (và tôi nghĩ rằng gets không phải là cách tiếp cận - với read, readpartial, read_nonblock).

2). Tôi thực sự đánh giá cao một vài dòng về cách thức đạt được điều này trong các máy chủ như kỳ lân hoặc hành khách

Cảm ơn bạn.

Trả lời

5

Nó thực hiện trong kỳ lân đây https://github.com/defunkt/unicorn/blob/master/lib/unicorn/http_request.rb#L69-L71

add_parse phương pháp (đọc các ý kiến ​​phương pháp trên) https://github.com/defunkt/unicorn/blob/master/ext/unicorn_http/unicorn_http.rl#L760-L778

Ngoài ra hãy xem xét một số lời giải thích đây http://www.ruby-forum.com/topic/2267632#1014288

Dưới đây là mã làm việc của bạn sử dụng 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

Cảm ơn bạn đã phản hồi và giới thiệu tôi với http_parser.rb. Biết về bất kỳ máy chủ nào không sử dụng thư viện trình phân tích cú pháp và chọn không cho một số cách tiếp cận khác? – Sid

+0

Tôi không biết các máy chủ không sử dụng các trình phân tích cú pháp, cách tiếp cận khác là gì? – Shtirlic

+0

Xin lỗi ý tôi là các máy chủ không sử dụng thư viện http_parser.rb. – Sid

Các vấn đề liên quan