1

Я запускаю BaseHTTPServer, прошедший через ThreadedHTTPServer, поэтому я получаю threading.Python BaseHTTPServer and Tornado

server = ThreadedHTTPServer(('', int(port)), MainHandler) 

Далее я вилка согласно информации здесь: Daemonizing python's BaseHTTPServer

Тогда я:

server.serve_forever() 

То, что я пытаюсь сделать, это есть один и тот же сценарий Python запустить сервер Торнадо WebSocket, как ну, я попытался создать второй обработчик и в моем основном создании второго сервера, подобного предыдущему, но затем блокировки serve_forever() (я предполагаю), и я не могу запустить сервер Tornado WebSocket.

Я рассматривал использование Tornado для обслуживания моего общего веб-материала, но производительность была беспомощной и непригодной для использования, поэтому я бы предпочел запустить ее вместе, если нет более простой альтернативы добавлению WebSockets в BaseHTTPServer.

Может ли кто-нибудь предложить решение, пожалуйста?

+0

"производительность была aweful и непригодным для использования"? Это должно быть довольно близко; как вы его протестировали? Несмотря на это, nginx должен быть самым быстрым способом обслуживания вашего «общего веб-материала». –

+0

Я пробовал обслуживать статическую старую html-страницу, и загрузка потребовала много секунд. Я думаю, в ретроспективе, это была моя ошибочная установка, а не вина Торнадо. – Hamid

ответ

3

Да, serve_forever() блокирует все это. Вы можете использовать handle_request для подачи одного запроса одновременно. Чтобы убедиться, что это не будет блокировать, вам нужно установить таймаут. Чтобы запустить его периодически, вы можете использовать tornado.ioloop.PeriodicCallback. Пример:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

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

import tornado.httpserver 
import tornado.ioloop 
import tornado.options 
import tornado.web 

from tornado.options import define, options 
define("port", default=8000, help="run on the given port", type=int) 

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.""" 

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     greeting = self.get_argument('greeting', 'Hello') 
     self.write(greeting + ', friendly user!\n') 

if __name__ == '__main__': 
    # create Tornado Server 
    tornado.options.parse_command_line() 
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)]) 
    http_server = tornado.httpserver.HTTPServer(app) 
    http_server.listen(options.port) 

    # create BaseHTTPServer 
    server = ThreadedHTTPServer(('localhost', 8080), Handler) 
    server.timeout = 0.01 

    tornado.ioloop.PeriodicCallback(server.handle_request, 100).start() # every 100 milliseconds 
    tornado.ioloop.IOLoop.instance().start() 

Продолжительность:

$ curl http://localhost:8080/ 
Thread-1 
$ curl http://localhost:8080/ 
Thread-2 
$ curl http://localhost:8000/ 
Hello, friendly user! 
$ curl http://localhost:8080/ 
Thread-3 
$ curl http://localhost:8000/ 
Hello, friendly user! 
$ curl http://localhost:8080/ 
Thread-4 
$ curl http://localhost:8000/ 
Hello, friendly user! 
$ curl http://localhost:8000/ 
Hello, friendly user! 

Я здесь timeout атрибут, чтобы установить тайм-аут. Я не уверен, что это правильный способ сделать это. Другой метод: http://code.activestate.com/recipes/499376/

Другое решение: работает каждый сервер в своем собственном потоке:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

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

import tornado.httpserver 
import tornado.ioloop 
import tornado.options 
import tornado.web 

from tornado.options import define, options 
define("port", default=8000, help="run on the given port", type=int) 

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.""" 

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     greeting = self.get_argument('greeting', 'Hello') 
     self.write(greeting + ', friendly user!\n') 

def run_tornado(): 
    tornado.options.parse_command_line() 
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)]) 
    http_server = tornado.httpserver.HTTPServer(app) 
    http_server.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 

def run_base_http_server(): 
    server = ThreadedHTTPServer(('localhost', 8080), Handler) 
    server.serve_forever() 

if __name__ == '__main__': 
    threading.Thread(target=run_tornado).start() 
    threading.Thread(target=run_base_http_server).start() 
+0

Ничего себе, спасибо за превосходно подробный ответ и за предоставленные варианты. Я запустил их обоих и посмотрю, какая из них лучше всего работает, но, безусловно, согласится на этот ответ. – Hamid

Смежные вопросы