#python #tornado
#python #tornado
Вопрос:
В моем файле python у меня есть два класса обработчиков: MainHandler (tornado.web.RequestHandler) и WebSocketHandler (tornado.web.WebSocketHandler). В классе MainHandler я выполняю следующий код в методе get:
class MainHandler(tornado.web.RequestHandler):
#some code
def get(self):
#some code
mainHandler_dict[chan] = self
await self.finish() #line of code that would do the waiting somehow
Итак, я сохраняю запрос в глобальном словаре, чтобы я мог вызывать request.write()
и request.finish()
в on_message
методе класса WebSocketHandler:
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def on_message(self, message):
#some code
request.write(body)
request.finish()
Я получаю переменную «request» из глобального словаря и пытаюсь вызвать write(), но возникает следующая ошибка: RuntimeError: Cannot write() after finish()
Я думаю, finish()
что он автоматически вызывается после завершения метода get в классе MainHandler. Итак, есть ли способ для RequestHandler продолжать «ждать», пока я не вызываю request.finish()
где-нибудь через файл?
Комментарии:
1. Ну, вы вызываете
finish
очень явно, а затем ждете возвращаемого значения.2. Но проблема в том, что когда я пытаюсь записать в
request.write(body)
, я думаю, что обработчик уже вызвалfinish()
себя. Моя строкаrequest.finish()
никогда не выполняется.3.Нет, вы вызываете
finish
здесь:await self.finish()
. Вы вызываете это. На этом запрос завершается.4. Если я не выполняю эту строку, я все равно получаю ту же ошибку. Эта строка — моя попытка дождаться, пока она будет вызвана где-то еще. Я думаю, это не работает таким образом.
5. Вам нужно не допустить завершения функции,
await
добавив что-то, что не позволит ей завершиться, пока она не получит значение. Я опубликовал решение ниже.
Ответ №1:
Вероятно, вам следует справиться с этим наоборот; не сохраняйте «запрос», постарайтесь каким-то образом сохранить его и записать в него из другого места, а скорее позвольте обработчику запроса дождаться, пока значение, которое вам нужно, станет доступным. Например.:
class MainHandler(RequestHandler):
async def get(self):
value = await magic()
self.write(value)
Теперь, как обрабатывать « magic
» часть, немного зависит от того, откуда берется это значение и что в вашем распоряжении, но давайте проиллюстрируем простым Future
:
async def get(self):
futures[chan] = asyncio.Future()
value = await futures[chan]
self.write(value)
И в других местах:
futures[chan].set_result(42)