使用Python BaseHTTPServer处理同时/异步请求

Dyl*_*uge 11 python simplehttpserver

我通过创建一个继承自HTTPServer和ThreadingMixIn的类来设置一个线程(使用Python线程)HTTP服务器:

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass
Run Code Online (Sandbox Code Playgroud)

我有一个继承自BaseHTTPRequestHandler的处理程序类,我用这样的东西启动服务器:

class MyHandler(BaseHTTPRequestHandler):
    ...

server = ThreadedHTTPServer(('localhost', 8080), MyHandler)
# Prevent issues with socket reuse
server.allow_reuse_address = True
# Start the server
server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

这一切都非常简单.我遇到的问题是,ThreadingMixIn,ForkingMixIn或其他方式,请求最终阻止请求处理程序返回.通过实现此示例代码可以很容易地看到这一点:

class MyHandler(BaseHTTPRequestHandler):
    def respond(self, status_code):
        self.send_response(status_code)
        self.end_headers()

    def do_GET(self):
         print "Entered GET request handler"
         time.sleep(10)
         print "Sending response!"
         respond(200)
Run Code Online (Sandbox Code Playgroud)

如果服务器同时处理这些,那么我们将能够发送两个请求并看到服务器在发送任何响应之前输入两个GET请求处理程序.相反,服务器将为第一个请求输入GET请求处理程序,等待它返回,然后输入第二个请求(因此第二个请求需要大约20秒才能返回而不是10).

有没有一种直接的方法让我实现一个系统,服务器不等待处理程序返回?具体来说,我正在尝试编写一个系统,在返回任何请求之前等待接收多个请求(一种长轮询)并遇到第一个请求等待阻止任何未来请求连接到服务器的问题.

jfs*_*jfs 15

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass
Run Code Online (Sandbox Code Playgroud)

足够.您的客户端可能不会发出并发请求.如果并行发出请求,则线程服务器按预期工作.这是客户:

#!/usr/bin/env python
import sys
import urllib2

from threading import Thread

def make_request(url):
    print urllib2.urlopen(url).read()

def main():
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
    for _ in range(10):
        Thread(target=make_request, args=("http://localhost:%d" % port,)).start()

main()
Run Code Online (Sandbox Code Playgroud)

和相应的服务器:

import time
from BaseHTTPServer   import BaseHTTPRequestHandler, HTTPServer, test as _test
from SocketServer     import ThreadingMixIn


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    pass

class SlowHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()

        self.wfile.write("Entered GET request handler")
        time.sleep(1)
        self.wfile.write("Sending response!")

def test(HandlerClass = SlowHandler,
         ServerClass = ThreadedHTTPServer):
    _test(HandlerClass, ServerClass)


if __name__ == '__main__':
    test()
Run Code Online (Sandbox Code Playgroud)

所有10个请求在1秒内完成.如果ThreadingMixIn从服务器定义中删除,那么所有10个请求都需要10秒才能完成.

  • 我是通过Google Chrome向服务器发送请求来测试的.事实证明,Chrome正在将我的请求序列化到同一台服务器,等待一台服务器返回,然后再发送下一台服务器.运行一个简单的Python脚本修复它.谢谢! (2认同)