it-swarm.com.de

Multithread-Webserver in python

Ich versuche, einen Multithread-Webserver in Python zu erstellen, aber er antwortet immer nur auf eine Anfrage und ich kann nicht herausfinden, warum. Kannst du mir bitte helfen?

#!/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()
48
user1937459

Check this Post aus Doug Hellmanns Blog.

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 __== '__main__':
    server = ThreadedHTTPServer(('localhost', 8080), Handler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()
73
root

Ich habe ein PIP-Dienstprogramm namens ComplexHTTPServer entwickelt, das eine Multithread-Version von SimpleHTTPServer ist.

Um es zu installieren, müssen Sie nur Folgendes tun:

pip install ComplexHTTPServer

Die Benutzung ist so einfach wie:

python -m ComplexHTTPServer [PORT]

(Standardmäßig ist der Port 8000.)

10
ViCky

In python3 können Sie den folgenden Code verwenden (https oder 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 __== '__main__':
    run()

Sie werden herausfinden, dass dieser Code einen neuen Thread erstellt, um jede Anfrage zu bearbeiten.

Befehl zum Generieren eines Selbstsignierzertifikats:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365

Wenn Sie Flask verwenden, ist dieses Blog großartig.

5
g10guang

Hier ist ein weiteres gutes Beispiel für einen HTTP-Server mit mehreren Threads wie SimpleHTTPServer: MultithreadedSimpleHTTPServer on GitHub .

3
GBC

Es ist erstaunlich, wie viele Stimmen diese Lösungen erhalten, die das Streaming unterbrechen. Wenn Streaming später erforderlich sein könnte, sind ThreadingMixIn und Gunicorn nicht gut, da sie nur die Antwort zusammenfassen und am Ende als Einheit schreiben (was eigentlich nichts bewirkt, wenn Ihr Stream unendlich ist).

Ihr grundlegender Ansatz, BaseHTTPServer mit Threads zu kombinieren, ist in Ordnung. Die Standardeinstellungen von BaseHTTPServer binden jedoch einen neuen Socket auf jedem Listener neu, was unter Linux nicht funktioniert, wenn sich alle Listener auf demselben Port befinden. Ändern Sie diese Einstellungen vor dem Aufruf von serve_forever(). (Genau wie Sie self.daemon = True In einem Thread setzen müssen, um zu verhindern, dass Strg-C deaktiviert wird.)

Im folgenden Beispiel werden 100 Handler-Threads auf demselben Port gestartet, wobei jeder Handler über BaseHTTPServer gestartet wird.

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)
3
personal_cloud