简体   繁体   English

具有多线程响应处理程序的Python http服务器

[英]Python http server with multithreaded response handlers

I'm trying to setup a python server that handles POST packets. 我正在尝试设置一个处理POST数据包的python服务器。 Once a packet arrives, The do_POST inits a new thread with self & some data, then, the thread does some stuff and puts into the self object received the output. 一旦数据包到达,do_POST就会在一个带有self和some数据的新线程中,然后,线程会做一些东西并放入收到输出的self对象中。 this is what I have so far: 这是我到目前为止:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
....
class httpHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers['content-length'])
        data = self.rfile.read(length)
        Resolver(self,data).start()
        return

Then, In my resolver class I do: import threading 然后,在我的解析器类中我做:导入线程

class Resolver(threading.Thread):
    def __init__(self,http,number):
        threading.Thread.__init__(self)
        self.http = http
        self.number = number + "!"

    def run(self):
        self.http.send_response(200)
        self.http.send_header('Content-type','text/html')
        self.http.send_header('Content-length', len(self.number))
        self.http.end_headers()
        # Send the html message
        self.http.wfile.write(self.number)
        return

Of course, this is an example and not the complete sheet, I'm still in the phase of testing my program. 当然,这是一个例子,而不是完整的表格,我仍处于测试我的程序的阶段。 It will be running over a weak platform (at the moment, Raspberry pi) and I'm looking for a good performance solution. 它将在弱平台上运行(目前,Raspberry pi),我正在寻找一个良好的性能解决方案。 any suggestions ? 有什么建议么 ?

The problem is that BaseHTTPRequestHandler expects you to be done with the request by the time you return from do_POST . 问题是BaseHTTPRequestHandler希望您在从do_POST返回时完成请求。 This isn't all that clear in the documentation, but it's immediately obvious if you look at the source to handle_one_request , the method that calls your method: 这在文档中并不是那么清楚,但是如果你看一下handle_one_request的源代码就会很明显,这是调用你的方法的方法:

mname = 'do_' + self.command
# ...
method = getattr(self, mname)
mname()
self.wfile.flush() #actually send the response if not already done.

If you look deeper, you'll see that, as you'd expect, the code expects to be able to close or reuse the connection as soon as it finishes handling a request. 如果你看得更深,你会发现,正如你所期望的那样,代码希望能够在完成处理请求后立即关闭或重用连接。

So, you can't use BaseHTTPRequestHandler this way. 因此,您不能以这种方式使用BaseHTTPRequestHandler

You can, of course, write your own handler implementation instead. 当然,您可以编写自己的处理程序实现。 To a large extent, the stuff in BaseHTTPServer is meant as sample code more than as a powerful, efficient, robust, and flexible framework (which is why the docs link straight to the source). 在很大程度上, BaseHTTPServer的东西更像是一个强大,高效,健壮且灵活的框架(这就是文档直接链接到源代码的原因)。

Alternatively, instead of trying to create a thread per request, just create a thread per connection. 或者,不是尝试为每个请求创建一个线程,而是每个连接创建一个线程。 The ThreadingMixIn class makes this easy. ThreadingMixIn类使这很容易。

But an even better solution would be to use a better framework, like Twisted or Tornado, or to use a webserver that does the threading for you and just calls your code via WSGI. 但更好的解决方案是使用更好的框架,如Twisted或Tornado,或者使用为您执行线程的Web服务器,并通过WSGI调用您的代码。

This is not the correct way to do this. 这不是正确的方法。 Now each thread that you send a request to is just going to be writing responses through the HTTP server "simultaneously". 现在,您发送请求的每个线程都将“同时”通过HTTP服务器写入响应。 You could add locking but that that would still defeat the purpose basically. 您可以添加锁定,但这仍然基本上会破坏目的。

Python already comes with a simple built-in way to do this. Python已经提供了一种简单的内置方法来实现这一点。 BaseHTTPServer.HTTPServer is a subclass of SocketServer.TCPServer so you can just use SocketServer.ThreadingMixIn . BaseHTTPServer.HTTPServerSocketServer.TCPServer的子类,因此您只需使用SocketServer.ThreadingMixIn The Python docs give an example here: Python文档在这里给出了一个例子:

http://docs.python.org/2/library/socketserver.html#asynchronous-mixins http://docs.python.org/2/library/socketserver.html#asynchronous-mixins

I'm sure there already exist examples of how to do this on SO too. 我确信已经存在如何在SO上执行此操作的示例。

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

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