3

参考:http ://docs.python.org/2/library/basehttpserver.html

Python BaseHTTPServer我有以下用于运行基本 HTTP 服务器的代码片段。

from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler

# http request handler
class HttpHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        print "I have just received a HTTP request through POST"

try:
    server = HTTPServer((<ip>, <port>), HttpHandler)

    # wait forever for incoming http requests!
    server.serve_forever()

except KeyboardInterrupt:
    server.socket.close()

我正在寻找的是一种在使用server.serve_forever()/方法启动/停止 http 服务器时获取回调的server.socket.close()方法。

假设我们有以下功能:

def http_server_start_callback():
    print "http server has just been started" 

def http_server_stop_callback():
    print "http server has just been stopped" 

我希望http_server_start_callback在我启动服务器之后(无论何时)立即调用函数server.serve_forever(),我希望http_server_stop_callback在我停止服务器之后(无论何时)立即调用函数,即server.socket.close()

使用以下回调配置 http 服务器会非常好:

  • 在启动服务器之前
  • 启动服务器后
  • 在停止服务器之前
  • 停止服务器后

有没有办法设置这些回调Python BaseHTTPServer.HTTPServer?!

4

2 回答 2

4

使用以下回调配置 http 服务器会非常好:

  • 在启动服务器之前
  • 启动服务器后
  • 在停止服务器之前
  • 停止服务器后

请记住,操作系统将在套接字开始侦听的那一刻开始接受和排队 TCP 连接,这是在 的构造函数中完成的BaseHTTPServer,因此如果您想在启动服务器之前执行冗长的任务,最好在操作系统之前执行它们开始接受连接。

有一种server_activate()方法可以调用socket.listen(),所以最好覆盖它。

socket.close()同样,操作系统将继续接受连接,直到server_close()调用而不是直接打电话socket.close()

我整理了一个简单的示例,使用请求处理程序上的类方法来处理四个新事件,尽管您可以将它们移动到其他地方......

from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler

# Subclass HTTPServer with some additional callbacks
class CallbackHTTPServer(HTTPServer):

    def server_activate(self):
        self.RequestHandlerClass.pre_start()
        HTTPServer.server_activate(self)
        self.RequestHandlerClass.post_start()

    def server_close(self):
        self.RequestHandlerClass.pre_stop()
        HTTPServer.server_close(self)
        self.RequestHandlerClass.post_stop()


# HTTP request handler
class HttpHandler(BaseHTTPRequestHandler):

    @classmethod
    def pre_start(cls):
        print 'Before calling socket.listen()'

    @classmethod
    def post_start(cls):
        print 'After calling socket.listen()'

    @classmethod
    def pre_stop(cls):
        print 'Before calling socket.close()'

    @classmethod
    def post_stop(cls):
        print 'After calling socket.close()'

    def do_POST(self):
        print "I have just received an HTTP POST request"


def main():

    # Create server
    try:
        print "Creating server"
        server = CallbackHTTPServer(('', 8000), HttpHandler)
    except KeyboardInterrupt:
        print "Server creation aborted"
        return

    # Start serving
    try:
        print "Calling serve_forever()"
        server.serve_forever()
    except KeyboardInterrupt:
        print "Calling server.server_close()"
        server.server_close()


if __name__ == '__main__':
    main()

请注意,我还将对构造函数的调用移到了它自己的try...except块中,因为server如果在构造过程中按 CTRL-C,该变量将不存在。

于 2013-05-30T13:47:19.230 回答
3

你必须继承HTTPServer并使用你的类HTTPServer

from __future__ import print_function
from BaseHTTPServer import HTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler


class MyHTTPServer(HTTPServer):


    def __init__(self, *args, **kwargs):

        self.on_before_serve = kwargs.pop('on_before_serve', None)
        HTTPServer.__init__(self, *args, **kwargs)

    def serve_forever(self, poll_interval=0.5):

        if self.on_before_serve:
            self.on_before_serve(self)
        HTTPServer.serve_forever(self, poll_interval)


# http request handler
class HttpHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        print("I have just received a HTTP request through POST")

try:
    server = MyHTTPServer(('0.0.0.0', 8080), HttpHandler,
                          on_before_serve = lambda server: print('Server will start to serve in the moment...'))

    # wait forever for incoming http requests!
    server.serve_forever()

except KeyboardInterrupt:
    server.socket.close()
于 2013-05-24T15:10:57.010 回答