Вызов Tornado WebSocketHandler из Requesthandler

Я использую веб-сервер Tornado и хочу внутренне вызвать WebSocketHandler из RequestHandler.

Невозможно использовать функцию перенаправления /redirectHandler, поскольку вызываемый класс WebSocketHandler ("IndexHandlerDynamic1" в приведенном ниже примере) будет создан с classFactory.

Используя определение Requesthandler (здесь) мой пример выглядит так:

class IndexHandlerDynamic1(tornado.web.WebSocketHandler):
    def initialize(self):
        print "Forwarded to Websocket"
    def open(self):
        print "WebSocket opened"
class IndexHandlerDistributor(tornado.web.RequestHandler):
    def get(self, channelId):
        IndexHandlerDynamic1(self.application, self.request)

Если я запрашиваю соответствующий URL-адрес, он переходит в IndexHandlerDistributor и вызывается IndexHandlerDynamic1.initialize().

Но на стороне клиента консоль браузера выводит следующую ошибку:

Error during WebSocket handshake: Unexpected response code: 200 

Очевидно, что соединение сокета открыто неправильно, в чем моя ошибка?

РЕДАКТИРОВАТЬ:

Спасибо Бену за помощь!

К сожалению, у меня все еще есть проблемы с маршрутизацией пользователя к динамически созданному классу, названному как параметр URL. Надеюсь, вы сможете понять мою проблему, взглянув на мой пример:

app = tornado.web.Application( 
        [(r"/", IndexHandler)] + 
        [(r"/channel/(?P<channelId>[^\/]+)?", ClassFactory(channelId))] 
        ) 

Как использовать channelId в качестве параметра для моего вызова ClassFactory в качестве обработчика запросов?

Или, может быть, есть другой способ динамически изменить маршрутизацию моего приложения во время работы приложения? Если это так, я мог бы использовать этот способ для решения моей первоначальной задачи.


person Whezz    schedule 29.07.2014    source источник


Ответы (1)


Проблема в том, что вы прикрепляете два RequestHandler к одному и тому же запросу. Я не уверен, что динамическое создание классов обработчиков — отличная идея, но если вы хотите сделать это, просто передайте свою фабричную функцию (которая сама по себе не является RequestHandler) в таблицу маршрутизации URL-адресов. Таблице маршрутизации не обязательно нужен подкласс RequestHandler, ей просто нужен объект, который можно вызвать с помощью (app, request) и вернуть экземпляр RequestHandler.

person Ben Darnell    schedule 30.07.2014
comment
Спасибо за полезное предложение! Я обновил свой вопрос, может быть, вы подскажете, как его решить. - person Whezz; 01.08.2014
comment
Проанализированные компоненты URL-адреса недоступны до тех пор, пока не будет вызван метод RequestHandler._execute, поэтому вы не сможете использовать их при создании экземпляра обработчика. Вы можете получить доступ к необработанному URL-адресу через атрибуты объекта запроса и самостоятельно проанализировать его на фабрике. - person Ben Darnell; 01.08.2014
comment
Большой! Спасибо за вашу помощь. Извлечение параметров из необработанного URL-адреса через атрибуты решило эту проблему. - person Whezz; 01.08.2014