3

BaseHttpServer我正在尝试使用and创建一个多线程 Web 服务器ThreadingMixIn(如在各种示例中所见)。伪代码类似于:

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
             pass
    def do_POST(self):
             pass

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""

if __name__ == '__main__':
    server = ThreadedHTTPServer(('localhost', 9999), Handler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

这可以按预期工作,但我的问题是并非每个请求都有一个线程,而是每个 URL 都完成了线程化。我已经像这样测试过它:我有一个绑定到执行以下方法的 URL:

import time
import datetime

def request_with_pause(self):
    print datetime.datetime.now().strftime("%H:%M:%S.%f"), 'REQUEST RECEIVED'
    time.sleep(10)
    print datetime.datetime.now().strftime("%H:%M:%S.%f"), 'SENT RESPONSE'

它工作正常,除非我在暂停5 秒的情况下调用 url 两次(单击 URL,等待 5 秒并再次单击它) - 两个“响应”都在 10 秒后到达(第一次单击的响应)。

4

1 回答 1

6

在 Python 2.7 中:

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from threading import Thread

class ThreadedHTTPServer(HTTPServer):
    def process_request(self, request, client_address):
        thread = Thread(target=self.__new_request, args=(self.RequestHandlerClass, request, client_address, self))
        thread.start()
    def __new_request(self, handlerClass, request, address, server):
        handlerClass(request, address, server)
        self.shutdown_request(request)

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write("hello world")

server = ThreadedHTTPServer(('', 80), Handler)
#server.serve_forever()

您可以在SocketServer.py中找到HTTPServer类的主要源代码,您可以在Python 目录的Lib文件夹中找到该文件。HTTPServer继承自TCPServerTCPServer继承自BaseServer。)

重要的一行是 315:

def process_request(self, request, client_address):
    self.finish_request(request, client_address)
    self.shutdown_request(request)

def finish_request(self, request, client_address):
    self.RequestHandlerClass(request, client_address, self)

此时,服务器使用您的 Handler 类创建新的请求对象。BaseRequestHandler构造函数自动调用 self.setup()、self.handle() 和 self.finish() 方法。

所以我所做的是重写 process_request 方法以将这些东西移动到新线程中。

于 2015-05-18T21:02:00.810 回答