Мне нужно сделать приложение, которое должно часто опрашивать сервер, но у GAE есть ограничения на запросы, поэтому выполнение большого количества запросов может быть очень дорогостоящим. Можно ли использовать долгий опрос и заставить запросы ждать максимум 30 секунд для изменений?
Возможен ли длинный опрос в Google App Engine?
Ответы (3)
В Google AppEngine появилась новая функция Channel API, благодаря которой у вас есть возможность создать хорошее приложение реального времени.
Другим решением является использование комет-сервера третьей части, такого как mochiweb или Twisted с шаблоном iframe.
Клиент1, ожидание события:
client1 --Iframe Pattern--> Erlang/Mochiweb(HttpLongPolling):
Клиент2, отправляет сообщение:
client2 --XhrIo--> AppEngine --UrlFetch--> Erlang/Mochiweb
Чтобы использовать mochiweb с кометным шаблоном, Ричард Джонс написал хорошую тему (в Google: Ричард Джонс, приложение Comet для миллиона пользователей).
Мы пытались внедрить в App Engine решение для длительного опроса, похожее на Comet, но с неоднозначными результатами.
def wait_for_update(request, blob):
"""
Wait for blob update, if wait option specified in query string.
Otherwise, return 304 Not Modified.
"""
wait = request.GET.get('wait', '')
if not wait.isdigit():
return blob
start = time.time()
deadline = start + int(wait)
original_sha1 = blob.sha1
try:
while time.time() < deadline:
# Sleep one or two seconds.
elapsed = time.time() - start
time.sleep(1 if elapsed < 7 else 2)
# Try to read updated blob from memcache.
logging.info("Checking memcache for blob update after %.1fs",
elapsed)
blob = Blob.cache_get_by_key_name(request.key_name)
# Detect changes.
if blob is None or blob.sha1 != original_sha1:
break
except DeadlineExceededError:
logging.info("Caught DeadlineExceededError after %.1fs",
time.time() - start)
return blob
Проблема, которую я вижу, заключается в том, что запросы, следующие за запросом с длинным опросом, сериализуются (синхронизируются) за запросом с длинным опросом. Я могу посмотреть на трассировку в Chrome и увидеть такую временную шкалу:
- Запрос 1 отправлен. GET (немодифицированный) большой двоичный объект (подождите, пока он не изменится).
- Запрос 2 отправлен. Измените большой двоичный объект.
- После полного тайм-аута Запрос 1 возвращается (данные не изменены).
- Запрос 2 обрабатывается на сервере и возвращает успех.
Я использовал wireshark и Chrome/timeline, чтобы подтвердить, что я отправляю запрос на изменение на сервер по другому TCP-соединению, отличному от соединения с длительным опросом. Таким образом, эта синхронизация должна происходить на рабочем сервере App Engine. Насколько мне известно, Google не документирует эту деталь поведения сервера.
Я думаю, что ожидание API канала — это лучшая надежда на то, что App Engine будет работать в режиме реального времени.
Я не думаю, что долгое голосование возможно. Время ожидания запроса по умолчанию для google appengine составляет 30 секунд. При длительном опросе, если для создания сообщения требуется более 30 секунд, произойдет сбой. Вероятно, вам лучше использовать короткий опрос.
Другой подход заключается в «симуляции» длительного опроса в пределах 30 секунд. Для этого, если сообщение не приходит в течение, скажем, 20 секунд, сервер может отправить «токеновое» сообщение вместо обычного сообщения, требуя от клиента его использования и повторного подключения.
Кажется, есть запрос функции (и он принят) на Google appengine для длинных опросов