Как «очистить» ответ в Pylons (аналог ASP Response.Write) - PullRequest
0 голосов
/ 11 марта 2010

У меня есть контроллер Pylons, который вызывается через jQuery $ .ajaxSubmit (). Он выполняет длительную операцию, и я хочу, чтобы он возвращал сообщения о ходе выполнения до того, как будет доступен весь вывод. В качестве простого доказательства концепции я попробовал это:

response.body_file.write('<script>OnExecutionProgress("Starting");</script>\n')
time.sleep(2)
response.body_file.write('<script>OnExecutionProgress("Finished");</script>\n')

Однако, это не возвращает первое сообщение клиенту немедленно - весь вывод возвращается только в конце.

Я уже делал что-то подобное в ASP.NET, используя Response.Write() и Response.Flush(), и это работало хорошо. Тем не менее, звонок response.body_file.flush() в Pylons не имеет значения.

Ответы [ 3 ]

1 голос
/ 11 марта 2010

Собственно, HTTP не поддерживает «потоковую передачу», которую вы, по-видимому, желаете - это протокол запроса / ответа, и не существует совместимого с протоколом способа отправки «части ответа». Скорее вы можете искать так называемые кометы техники. Пример кометы с пилонами: здесь .

0 голосов
/ 28 января 2012

Вы можете «выдать» свой блок результатов за раз. Попробуйте написать генератор, который выдает блок результатов за раз, и он, вероятно, будет работать. Использует http://en.wikipedia.org/wiki/Chunked_transfer_encoding.

0 голосов
/ 23 марта 2010

Это определенно хак, но в пилонах он работает так же, как в ASP.NET. Я проверил это на сервере вставки.

Как сказал Алекс Мартелли, в этом случае лучше использовать Comet. Подача скрипта chunk by chunk может привести к следующим проблемам:

  1. это не поддерживается и зависит от реализации сервера;
  2. ненадежно, так как вы не можете обработать тайм-ауты соединения;
  3. серверу необходимо выделить отдельный поток для каждого соединения, что может стать узким местом производительности на сайтах с высокой нагрузкой

Прежде всего вы должны отключить отладку в development.ini:

debug = false

Вот код контроллера:

class HelloController(BaseController):
    def index(self):
        header = '''\
<html><head><title>test page</title>
<script type="text/javascript">
function foo(i) {
document.getElementById('counter').innerHTML = i;
}
</script>
</head>
<body>
<div id="counter">
</div>
'''
        footer = '''\
</body>
</html>
'''
        progress = ('<script>foo(%i);</script>' % i for i in xrange(0,101,2))
        def f():
            yield header
            for script in progress:
                time.sleep(1)
                yield script
            yield footer
        return f()
...