我正在尝试使用 BaseHttpServer
和 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 绑定(bind)来执行以下方法:
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'
它工作正常,除非我调用 url 两次,暂停 5 秒(单击 URL,等待 5 秒,然后再次单击它)- 两个“响应”都在 10 秒后到达(第一次点击的响应)。
在 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继承自TCPServer,TCPServer继承自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)
此时服务器使用您的处理程序类创建新的请求对象。 BaseRequestHandler 构造函数自动调用 self.setup()、self.handle() 和 self.finish() 方法。
所以我所做的就是重写 process_request 方法以将这些内容移动到新线程中。
我是一名优秀的程序员,十分优秀!