Ruby Http服务器在单独的线程中

时间:2014-08-13 07:33:42

标签: ruby multithreading http tcp

我使用https://practicingruby.com/articles/implementing-an-http-file-server?u=dc2ab0f9bb上的代码在Ruby中启动一个简单的http服务器。

此代码效果很好。但是,server.accept调用和循环会阻塞主线程。我已将代码更改为以下内容:

require 'socket' # Provides TCPServer and TCPSocket classes

#start the server thread
server_thread = Thread.start do

    # Initialize a TCPServer object that will listen
    # on localhost:2345 for incoming connections.
    server = TCPServer.new('localhost', 2345)

    # loop infinitely
    loop do

      # use a seprate thread, acception multiple incoming connections
      Thread.start(server.accept) do |socket|

          # Read the first line of the request (the Request-Line)
          request = socket.gets

          response = "Hello World!\n"

          # We need to include the Content-Type and Content-Length headers
          # to let the client know the size and type of data
          # contained in the response. Note that HTTP is whitespace
          # sensitive, and expects each header line to end with CRLF (i.e. "\r\n")
          socket.print "HTTP/1.1 200 OK\r\n" +
                       "Content-Type: text/plain\r\n" +
                       "Content-Length: #{response.bytesize}\r\n" +
                       "Connection: close\r\n"

          # Print a blank line to separate the header from the response body,
          # as required by the protocol.
          socket.print "\r\n"

          # Print the actual response body, which is just "Hello World!\n"
          socket.print response

          # Close the socket, terminating the connection
          socket.close

      end#do
    end#do
end#do

这样主线程就不会阻塞,因为服务器在一个单独的线程中运行。但是,现在当我浏览http://localhost:2345/时,我得不到回报。

如何在单独的线程中运行服务器?

重要的是要知道这个脚本在一个接受Ruby插件的应用程序中运行。因此,它不像主线程将终止,导致子线程接近。

1 个答案:

答案 0 :(得分:1)

以下是解决方案:

require 'socket' # Provides TCPServer and TCPSocket classes

#start the server thread
server_thread = Thread.start do

    # Initialize a TCPServer object that will listen
    # on localhost:2345 for incoming connections.
    server = TCPServer.new('localhost', 2345)

    # loop infinitely
    loop do
      puts "Server started"
      # use a seprate thread, acception multiple incoming connections
      Thread.start(server.accept) do |socket|

          # Read the first line of the request (the Request-Line)
          request = socket.gets

          response = "Hello World!\n"

          # We need to include the Content-Type and Content-Length headers
          # to let the client know the size and type of data
          # contained in the response. Note that HTTP is whitespace
          # sensitive, and expects each header line to end with CRLF (i.e. "\r\n")
          socket.print "HTTP/1.1 200 OK\r\n" +
                       "Content-Type: text/plain\r\n" +
                       "Content-Length: #{response.bytesize}\r\n" +
                       "Connection: close\r\n"

          # Print a blank line to separate the header from the response body,
          # as required by the protocol.
          socket.print "\r\n"

          # Print the actual response body, which is just "Hello World!\n"
          socket.print response

          # Close the socket, terminating the connection
          socket.close

      end#do
    end#do
end#do

spam_thread = Thread.start do
  loop do
    puts "Another thread"
    sleep 1
  end
end

server_thread.join
spam_thread.join

join导入从主线程产生的所有线程,因为如果主线程完成,每个未连接的线程都被杀死。在示例中一切正常,因为主线程处于占用的无限循环中主线程,在您创建服务器线程后,主线程立即完成。