简体   繁体   English

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

[英]Ruby Http server in separate thread

I'm using the code found on https://practicingruby.com/articles/implementing-an-http-file-server?u=dc2ab0f9bb to start a simple http server in Ruby. 我正在使用https://practicingruby.com/articles/implementing-an-http-file-server?u=dc2ab0f9bb上找到的代码在Ruby中启动简单的http服务器。

This code works great. 这段代码很棒。 However, the server.accept call and the loop do block up the main thread. 但是,server.accept调用和循环确实会阻塞主线程。 I've changed the code to the following: 我将代码更改为以下内容:

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

This way the main Thread doesn't block, as the server runs in a separate thread. 这样,由于服务器在单独的线程中运行,因此主线程不会阻塞。 But, now when I browse to http://localhost:2345/ I get no return. 但是,现在当我浏览到http://localhost:2345/没有任何回报。

How can I run a server in a separate thread? 如何在单独的线程中运行服务器?

Important to know is that this script runs in an application that accepts Ruby plugins. 重要的是要知道此脚本在接受Ruby插件的应用程序中运行。 So, it's not like the main thread will terminate, causing the sub thread to close to. 因此,这并不意味着主线程将终止,从而导致子线程关闭。

Here is the solution: 解决方法如下:

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

It is import to join all the threads spawned from the main thread, because every non-joined thread is killed if the main thread finished.In the example everything works because the main thread is in infinite loop that occupies the main thread, in your case the main thread finishes immediatly after you create the server thread. 重要的是要join从主线程产生的所有线程,因为在主线程完成后,所有未连接的线程都会被杀死。在本例中,一切正常,因为主线程处于无限循环中,占用了主线程创建服务器线程后,主线程立即完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM