AppEngine Channel API — лучший способ проверить, открыт ли канал (на стороне сервера)

Я создал приложение типа социальной сети/знакомств на AppEngine и в настоящее время добавляю чат, построенный поверх Channel API. Однако проблема, с которой я сталкиваюсь, заключается в том, что пользователи могут перезагружать или переходить на новые страницы во время чата (как они могут в Facebook). Это означает, что серверу нелегко узнать, должен ли он генерировать новый токен идентификатора канала для данного клиента или данному клиенту уже был назначен токен канала.

Было бы очень полезно, если бы был способ проверить (на стороне сервера), есть ли у конкретного клиента уже открытый канал. Например, если я назначу клиенту "Джек" идентификатор канала "Джек-январь-21-2010", то я хотел бы иметь возможность проверить на стороне сервера, есть ли уже открытый канал, связанный с идентификатором " Джек-январь-21-2010». Это можно (как бы) отследить на стороне клиента, наблюдая за обратными вызовами onerror() и onclose(), но я не вижу ничего на стороне сервера, что позволило бы мне просто проверить, является ли канал, связанный с данным идентификатором, уже открыто.

Кто-нибудь знает интеллектуальный способ проверить (на стороне сервера), был ли канал уже открыт, при использовании API канала AppEngine?


person Alexander Marquardt    schedule 26.01.2011    source источник


Ответы (1)


Часть 1: Решение вашей проблемы

См. Часть 2 ниже, если вам действительно нужно отслеживать клиентские подключения, но я не уверен, исходя из вашего вопроса, решит ли то, о чем вы просите, вашу проблему.

Позвольте мне посмотреть, могу ли я повторить вашу проблему: вы пишете приложение для чата, но оно предназначено для сайта, который не полностью поддерживает AJAX (как, скажем, gmail); сайт содержит навигацию по страницам, где вам может потребоваться перенастроить свой канал после того, как пользователь нажмет ссылку на другую страницу. Когда пользователь перемещается, отображается новая страница, и вы хотите избежать получения нового маркера в этот момент; вы хотите повторно использовать существующий токен и канал с тем же идентификатором клиента.

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

  • Сохраните токен в файле cookie. Когда вы повторно отображаете свою страницу, просто используйте токен из файла cookie вместо повторного вызова channel.create_channel. Когда срок действия токена истечет, вы получите обратный вызов onerror, как если бы пользователь остался на исходной странице; в этот момент снова вызовите channel.create_channel. Проблема с этим заключается в том, что повторное подключение может быть медленным (до 10 секунд или более в плохих случаях) из-за характера соединений Comet.

  • Оберните весь свой сайт, не связанный с чатом, в iframe. Поместите код создания канала и пользовательский интерфейс во внешний iframe. Таким образом, вам не нужно повторно подключаться каждый раз, когда пользователь перемещается. Это позволяет избежать простоев в навигации. Обратите внимание, что orkut использует эту технику с плавающими элементами div, как показало небольшое исследование Firebug.

Часть 2: Ваш запрос функции

Если выяснится, что я неправильно понимаю, и вам действительно нужно отслеживать клиентские соединения:

Нет встроенного способа проверить, подключен ли клиент к каналу, идентифицированному идентификатором клиента.

Однако прямо сейчас я работаю над добавлением «присутствия» (в смысле чата), чтобы ваше приложение могло зарегистрироваться для получения сообщения, когда клиент подключается к каналу, созданному с заданным идентификатором клиента, или отключается от него. Вы также можете «прощупать» присутствие, чтобы узнать, подключен ли данный идентификатор клиента или нет (все еще работая над деталями этой части).

Обратите внимание, что это будет не токен, а идентификатор клиента.

У меня пока нет точной даты релиза, но, как я уже сказал, я активно работаю над этим прямо сейчас.

Тем временем вы можете использовать HTTP-запрос Heartbeat от вашего клиента обратно к вашему приложению, который говорит: «Эй, я все еще здесь» каждую минуту или около того. Вам понадобится какая-то задача, которая запускается, скажем, каждые 2 минуты и помечает всех клиентов, которые не зарегистрировались, как неактивные, и вам нужно будет где-то хранить эти данные.

person Moishe Lettvin    schedule 26.01.2011
comment
Вау, отличный ответ. Я собираюсь переварить это в течение следующих нескольких часов. Спасибо и добрые пожелания. -Алекс - person Alexander Marquardt; 26.01.2011
comment
Вы точно повторили мою проблему, и решения, которые вы предложили, кажутся разумными обходными путями. Я думаю, что решение iframe выглядит интересно и, вероятно, решит мою проблему. - person Alexander Marquardt; 26.01.2011
comment
Мойше, я угощу тебя вкусным саммичем из индейки, если ты проявишь себя в следующем выпуске. спасибо :) - person Nick Franceschina; 14.02.2011
comment
Почему сердцебиение должно быть в POST? - person Davide Ungari; 18.03.2011
comment
Извините за это, это не обязательно должен быть POST. Просто какой-то HTTP-запрос. - person Moishe Lettvin; 21.03.2011
comment
Не надейтесь на бутерброд с индейкой, но ознакомьтесь с заметками перед выпуском версии 1.5.1 :) groups.google.com/group/google-appengine/browse_thread/thread/ - person Moishe Lettvin; 15.06.2011
comment
Есть ли в новом API способ проверить, открыт ли канал? ChannelPresence имеет значение isConnected. Но как получить ChannelPresence, если у меня есть только clientId. Я хочу удалить/повторно использовать токен всякий раз, когда сервер говорит Пропустить сообщение для неподключенного канала: [...]. - person Dominik; 27.01.2012