我有两个关于从套接字读取的问题以及如何在像Unicorn或Mongrel这样的Ruby服务器上进行管理
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
我想知道Ruby服务器使用的最佳实践/标准方法。我看到Unicorn使用来自kgio库的read_nonblock而mongrel使用了readpartial(我不确定这些但是通过代码这就是我认为采用的方法。)即使检查\ r \ n如何服务器是否知道输入已完成。
可以解释如何做到这一点(我认为gets
不是方法 - 它与read
,readpartial
,read_nonblock
)。
2)。我真的很感激如何在像独角兽或乘客这样的服务器中实现这一点
谢谢。
答案 0 :(得分: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