Отправка данных после запроса URL - PullRequest
8 голосов
/ 05 апреля 2010

Учитывая, что когда пользователь запрашивает /foo на моем сервере, я отправляю следующий HTTP-ответ (не закрывая соединение):

Content-Type: multipart/x-mixed-replace; boundary=-----------------------

-----------------------
Content-Type: text/html

<a href="/bar">foo</a>

Когда пользователь переходит на /bar (который отправит204 No Content чтобы представление не изменилось), я хочу отправить следующие данные в первоначальном ответе.

-----------------------
Content-Type: text/html

bar

Как получить второй запрос для инициирования этого из исходного ответа?Я планирую, возможно, создать причудливый [движки, которые поддерживают multipart / x-mixed-replace (в настоящее время только Gecko)] - единственное почтовое веб-приложение, которое выполняет эффекты server-push и Ajax без JavaScript, просто для удовольствия.

Ответы [ 4 ]

1 голос
/ 20 апреля 2010

Я создал небольшой пример (просто для забавы, вы знаете:))

import threading

num = 0
cond = threading.Condition()

def app(environ, start_response):
    global num

    cond.acquire()
    num += 1
    cond.notifyAll()
    cond.release()

    start_response("200 OK", [("Content-Type", "multipart/x-mixed-replace; boundary=xxx")])
    while True:
        n = num    
        s = "--xxx\r\nContent-Type: text/html\r\n\r\n%s\n" % n
        yield s
        # wait for num change:
        cond.acquire()
        while num == n:
            cond.wait()
        cond.release()


from cherrypy.wsgiserver import CherryPyWSGIServer
server = CherryPyWSGIServer(("0.0.0.0", 3000), app)

try:
    server.start()
except KeyboardInterrupt:
    server.stop()

# Now whenever you visit http://127.0.0.1:3000/, the number increases.
# It also automatically increases in all previously opened windows/tabs.

Идея общей переменной и синхронизации потока (с использованием объекта условной переменной) основана на том факте, что сервер WSGI, предоставляемый CherryPyWSGIServer, является многопоточным.

1 голос
/ 20 апреля 2010

Нет полного ответа, но:

В своем вопросе вы описываете архитектуру в стиле Comet . Что касается поддержки методов в стиле Comet в Python / WSGI, существует вопрос StackOverflow , в котором говорится о различных серверах Python с поддержкой долгосрочных запросов в виде Comet.

Также интересен этот почтовый поток в Python Web-SIG: «Может ли WSGI обрабатывать асинхронный ответ?» . В мае 2008 года в Web-SIG состоялась широкая дискуссия на тему асинхронных запросов в WSGI .

.

Недавняя разработка - evserver , облегченный сервер WSGI, который реализует Асинхронное расширение WSGI , предложенное Кристофером Ставарцем в Web-SIG в мае 2008 года.

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

1 голос
/ 05 апреля 2010

Если проблема состоит в том, чтобы передать какую-то команду из приложения / bar в приложение / foo, и вы используете какой-то сервлетный подход (код Python загружается один раз, а не для каждого запроса, как в CGI), вы можете просто изменить некоторые свойство класса приложения / foo и будьте готовы отреагировать на изменение в экземпляре / foo (проверив состояние свойства).

Очевидно, что приложение / foo не должно возвращаться сразу после первого запроса и выводить содержимое построчно.

Думал, что это всего лишь теория, я сам этого не пробовал.

0 голосов
/ 05 апреля 2010

Не уверен, что это именно то, что вам нужно, но есть довольно старый способ выполнения push-сообщений с использованием mime-содержимого multipart / x-mixed-replace

По сути, вы составляете ответкак объект MIME с типом содержимого multipart / x-mixed-replace и отправкой первой «версии» документа.Браузер будет держать сокет открытым.

Затем, когда сервер решит отправить больше данных, с сервера будет отправлена ​​новая «версия» документа, и браузер разумно заменит (в пределах любого фрейма / фрейма, в котором содержится контент) контент.

Это был ранний способ создания веб-камер, когда сервер отправлял (проталкивал) изображение за изображением, а браузер просто продолжал заменять изображение в документе снова и снова.Это также способ сделать сообщение «Загрузка ...» по одному HTTP-запросу.

...