multithreading - Python 2.7: streaming HTTP server supporting multiple connections on one port -


i looking standard python 2.7 package providing http server simultaneous streaming connections on same port number.

hey moderators out there, please stop flagging question duplicate of questions want serve in non-streaming ways, one: multithreaded web server in python. no, don't want hack such threadingmixin merely collects response , returns unit.

in other words, i'm looking standard way following example program -- without writing whole http server myself.

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)  # own http server... oh man, bad style. 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 biting ctrl-c         self.start()      def run(self):         conn, addr = sock.accept()         conn.send(http)          # serve infinite stream         = 0         while true:             conn.send("%i " % i)             time.sleep(0.1)             += 1  [listener() in range(100)] time.sleep(9e9) 

so first tried:

# run command: #    gunicorn -k gevent myapp:app import time  def app(environ, start_response):     data = b"hello, world!\n"     start_response("200 ok", [         ("content-type", "text/plain"),         ("content-length", str(len(data)))     ])     in range(5):         time.sleep(1)         yield "hello %i\n" %  # https://stackoverflow.com/questions/22739394/streaming-with-gunicorn 

but unfortunately doesn't stream, -k gevent.

update: appears gunicorn trying keepalive, require chunked transfer coding last-chunk bit. quick grep of sources reveals it's not implementing that. might need fancier http server, or simpler 1 (like first example above, based on socket) doesn't bother keepalive (which pretty silly large streams anyway).

so tried:

import time import threading  import 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 infinite stream         = 0         while true:             self.wfile.write("%i " % i)             time.sleep(0.1)             += 1  class listener(threading.thread):      def __init__(self, i):         threading.thread.__init__(self)         self.i =         self.daemon = true         self.start()      def run(self):         server_address = ('', 8000+self.i) # how attach of them 8000?         httpd = basehttpserver.httpserver(server_address, handler)         httpd.serve_forever()  [listener(i) in range(100)] time.sleep(9e9) 

which pretty good, it's bit annoying have allocate 100 port numbers. require obnoxious client-side redirect browser next available port (well, ok, can hide javascript, it's not elegant. i'd rather write own http server that).

there must clean way basehttpserver listeners on 1 port, such standard way of setting web server. or maybe gunicorn or somesuch package can made stream reliably?

the default basehttpserver settings re-bind new socket on every listener, won't work in linux if listeners on same port. change settings between basehttpserver.httpserver() call , serve_forever() call.

the following example launches 100 handler threads on same port, each handler started through 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 infinite stream         = 0         while true:             self.wfile.write("%i " % i)             time.sleep(0.1)             += 1  # create 1 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 =         self.daemon = true         self.start()     def run(self):         httpd = basehttpserver.httpserver(addr, handler, false)          # prevent http server 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) in range(100)] time.sleep(9e9) 

Comments

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -