我想在Python中创建多线程的Web服务器,但只响应一次一个请求,我想不通为什么。 你能帮我吗?
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from time import sleep
class ThreadingServer(ThreadingMixIn, HTTPServer):
pass
class RequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
sleep(5)
response = 'Slept for 5 seconds..'
self.send_header('Content-length', len(response))
self.end_headers()
self.wfile.write(response)
ThreadingServer(('', 8000), RequestHandler).serve_forever()
检查这个职位由道格·赫尔曼的博客。
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import threading
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
message = threading.currentThread().getName()
self.wfile.write(message)
self.wfile.write('\n')
return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
if __name__ == '__main__':
server = ThreadedHTTPServer(('localhost', 8080), Handler)
print 'Starting server, use <Ctrl-C> to stop'
server.serve_forever()
我公司开发的PIP工具叫做ComplexHTTPServer是SimpleHTTPServer的多线程版本。
要安装它,所有你需要做的是:
pip install ComplexHTTPServer
使用它很简单:
python -m ComplexHTTPServer [PORT]
(默认情况下,端口是8000)
这里是一个多线程SimpleHTTPServer般的HTTP服务器的另一个很好的例子: MultithreadedSimpleHTTPServer GitHub上 。
它是惊人的多少票,这些解决方案,打破流越来越。 如果可能需要流在路上,然后ThreadingMixIn
和gunicorn没有好,因为他们只是收集了响应,并在年底写为单位(实际上什么也不做,如果你的流是无限的)。
你相结合的基本方法BaseHTTPServer
与线程的罚款。 但默认BaseHTTPServer
设置重新绑定在每一个听众,如果所有的听众是同一个端口上,不会在Linux下工作一个新的套接字。 在之前更改这些设置serve_forever()
调用。 (就像你必须设置self.daemon = True
上一个线程被禁用停止CTRL-C)。
下面的例子启动同一端口100个处理器线程,每个处理器通过启动BaseHTTPServer
。
import time, threading, socket, SocketServer, BaseHTTPServer
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path != '/':
self.send_error(404, "Object not found")
return
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
# serve up an infinite stream
i = 0
while True:
self.wfile.write("%i " % i)
time.sleep(0.1)
i += 1
# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)
# Launch 100 listener threads.
class Thread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.i = i
self.daemon = True
self.start()
def run(self):
httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)
# Prevent the HTTP server from re-binding every handler.
# https://stackoverflow.com/questions/46210672/
httpd.socket = sock
httpd.server_bind = self.server_close = lambda self: None
httpd.serve_forever()
[Thread(i) for i in range(100)]
time.sleep(9e9)
在python3,你可以使用下面的代码(HTTPS或HTTP):
from http.server import HTTPServer, BaseHTTPRequestHandler
from socketserver import ThreadingMixIn
import threading
USE_HTTPS = True
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello world\t' + threading.currentThread().getName().encode() + b'\t' + str(threading.active_count()).encode() + b'\n')
class ThreadingSimpleServer(ThreadingMixIn, HTTPServer):
pass
def run():
server = ThreadingSimpleServer(('0.0.0.0', 4444), Handler)
if USE_HTTPS:
import ssl
server.socket = ssl.wrap_socket(server.socket, keyfile='./key.pem', certfile='./cert.pem', server_side=True)
server.serve_forever()
if __name__ == '__main__':
run()
你会弄明白这些代码将创建一个新的线程来处理每一个请求。
以下命令来生成自签名证书:
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
如果您使用的瓶, 这个博客是伟大的。