0

I am trying to create multi threaded web server in python, but the requests are handled one by one. After searching few hours, I found this link but the approved answer seems to be incorrect as the request over there is also handled one by one. Here is the code:

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import threading
from time import sleep

class Handler(BaseHTTPRequestHandler):

def do_GET(self):
    self.send_response(200)
    self.end_headers()
    sleep(5)
    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()

I added "sleep(5)" for 5 second delay to handle the request. After that I send multiple requests but all the requests are handled one by one and each request took 5 seconds. I am unable to find the reason. Help me.

6
  • 1
    Why are you writing a web server yourself? There are plenty already. Use gunicorn or uwsgi. Commented Aug 20, 2017 at 18:13
  • Your observations are incorrect. The code as shown above (when you fix the indentation!) works as intended; it is able to start serving a GET request in a new thread while the other(s) are still being processed. I don't know how you reached the conclusion that it doesn't work. Commented Aug 20, 2017 at 21:55
  • @IrmendeJong Sir, there is no issue with indentation. The test I conducted gives me result one after other. You can try the above code. Commented Aug 21, 2017 at 7:00
  • I did, and it works fine. I suggest you look at docs.python.org/3.7/library/… Commented Aug 21, 2017 at 11:39
  • and yes, you have an indendtation error in your code: the "def" should be indented to be part of the class Commented Aug 21, 2017 at 21:50

1 Answer 1

0

The key requirement here is to be able to have a 5-second delay between the send_response and the data returned. That means you need streaming; you can't use ThreadingMixIn, gunicorn, or any other such hack.

You need something like this:

import time, socket, threading

sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 8000

sock.bind((host, port))
sock.listen(1)

HTTP = "HTTP/1.1 200 OK\nContent-Type: text/html; charset=UTF-8\n\n"

class Listener(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True # stop Python from biting ctrl-C
        self.start()

    def run(self):
        conn, addr = sock.accept()
        conn.send(HTTP)

        # serve up an infinite stream
        i = 0
        while True:
            conn.send("%i " % i)
            time.sleep(0.1)
            i += 1

[Listener() for i in range(100)]
time.sleep(9e9)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.