API канала Google App Engine

Я пытаюсь изучить API канала GAE (используя Java), но не могу понять, с чего начать.

Я просмотрел обзор API канала (Java), но код опубликован не было полным для краткости.

И поскольку я новичок, было бы очень полезно, если бы был доступен полный пример кода.

Спасибо, Шри


person Shrey    schedule 25.11.2011    source источник


Ответы (2)


Код в Обзоре API канала, на который вы ссылаетесь, довольно полный, он просто немного разбросан. Я признаю, как только вы это поймете, я почувствую, что это намного проще, чем они представили, но я рад, что они ошиблись, предоставив слишком много информации.

Немного сложно дать полное решение для этого без просачивания посторонней информации, поскольку то, как вы будете использовать API канала, немного зависит от существующей инфраструктуры вашего приложения. По этой причине я попытался немного рассказать о том, что предоставляет документация AppEngine, чтобы, надеюсь, вы могли лучше понять. А комментарии позволят вам задать конкретные вопросы, если они у вас возникнут.

Для начала немного словарного запаса:

  • Сообщение канала. Сообщение, которое вы хотите отправить клиентам (и, вероятно, основная причина, по которой вы используете API канала).
  • Ключ канала. Строка, уникальная для пользователя и области, в которой пользователь пытается отправить сообщение.
  • Идентификатор канала. Строка, уникальная для любого клиента. 1 токен канала на клиента за 2 часа.
  • Channel Service: серверный класс AppEngine, предоставляющий средства для создания каналов и отправки по ним сообщений канала.

На сервере вам нужно будет выполнить следующее:

ChannelService channelService = ChannelServiceFactory.getChannelService();

// The channelKey can be generated in any way that you want, as long as it remains
// unique to the user.
String channelKey = "xyz";
String token = channelService.createChannel(channelKey);

Когда у вас есть токен, вам просто нужно каким-то образом передать его коду на стороне клиента. Документ AppEngine, на который вы ссылаетесь, делает это, предоставляя HTML-код из сервлета Java и вызывая index.replaceAll("\\{\\{ token \\}\\}", token).

Как это работает, они поместили литеральную строку {{ token }} в свой код JavaScript (как вы увидите ниже), поэтому везде, где {{ token }} появляется в коде JavaScript, он будет заменен фактическим токеном, сгенерированным вызовом channelService.createChannel(...). выше. Обратите внимание, что вам не нужно вводить токен в клиентский код, который вы обслуживаете таким образом, но это хорошее место для начала, поскольку именно так они это и сделали ( и задокументировал это).


Теперь, когда вы внедрили токен в JavaScript, вам нужно отправить код с токеном канала клиенту. (Обратите внимание, что, как указано выше, вы также можете передать клиенту только токен и таким образом создать канал). Код у них такой:

<body>
  <script>
    channel = new goog.appengine.Channel('{{ token }}');
    socket = channel.open();
    socket.onopen = onOpened;
    socket.onmessage = onMessage;
    socket.onerror = onError;
    socket.onclose = onClose;
  </script>
</body>

Они вырезали детали того, как читать это из файла на сервере, но опять же, вы можете сделать это как угодно. Вы также можете просто напечатать строку, используя resp.getWriter().print(index) в своем JavaServlet, где index — это строка, в которой хранится содержимое HTML/JavaScript, указанное выше. Как я сказал изначально, многое зависит от вас, что лучше всего подходит для существующей инфраструктуры вашего приложения.

Они предназначены для того, чтобы вы определили свои собственные функции JavaScript onOpened, onMessage, onError и onClose, которые будут вызываться при открытии каналов, получении сообщения, обнаружении ошибки или закрытии соответственно. Вы можете просто создать наивные реализации, чтобы лучше понять, что происходит:

function onOpened() {
    alert("Channel opened!");
}

function onMessage(msg) {
    alert(msg.data);
}

function onError(err) {
    alert(err);
}

function onClose() {
    alert("Channel closed!");
}

Я по-прежнему рекомендую разделить их на отдельные функции, чтобы вам было легче расширять их, чтобы поиграть и разобраться. Дополнительные сведения об API JavaScript см. в Справочнике по JavaScript API канала.


Вам потребуется создать механизм для получения данных, которые вы хотите отправить с клиента на сервер. Опять же, как вы хотите это сделать, не имеет значения. Документация AppEngine предлагает настроить XMLHttpRequest для этой цели.

sendMessage = function(path, opt_param) {
  path += '?g=' + state.game_key;
  if (opt_param) {
    path += '&' + opt_param;
  }
  var xhr = new XMLHttpRequest();
  xhr.open('POST', path, true);
  xhr.send();
};

Здесь opt_param — это просто строка необязательных параметров в формате x=1&y=2&z=3. Это вся инфраструктура, которую они построили для своего примера приложения Tic-Tac-Toe, и она не имеет решающего значения для функциональности Channel API; как я уже сказал, вы можете сделать этот звонок, как хотите.

path — это путь к вашему сервлету (который вам нужно настроить в файле web.xml), который должен обрабатывать отправку и получение сообщений (см. следующий раздел).


После того как вы отправили сообщение от клиента на сервер, вам понадобится сервлет, который может отправить обновление всем клиентам с одним и тем же ключом канала.

ChannelService channelService = ChannelServiceFactory.getChannelService();

// This channelKey needs to be the same as the one in the first section above.
String channelKey = "xyz"

// This is what actually sends the message.
channelService.sendMessage(new ChannelMessage(channelKey, "Hello World!"));

Вышеприведенный вызов channelService.sendMessage(...) — это то, что фактически отправляет сообщение, чтобы оно могло быть получено функцией onMessage, которую вы определили в предыдущем разделе.


Я надеюсь, что этот ответ является полным (и, если на то пошло, правильным) достаточно, чтобы помочь вам начать работу. Большую часть того, что они поместили в документы (и мой код здесь), можно скопировать и вставить с небольшими изменениями.

person Jon Newmuis    schedule 25.11.2011
comment
Большое вам спасибо :) Меня смутил этот .. index.replaceAll(\\{\\{токен \\}\\}, токен) и теперь я могу начать .. :) - person Shrey; 26.11.2011
comment
Он работает нормально .. :), как я могу отправить сообщение по многоадресной рассылке ..? есть ли API для этого? - person Shrey; 27.11.2011
comment
этот ответ заслуживает какой-то награды :) - person HaveAGuess; 16.02.2012
comment
Вы говорите, что один вызов sendMessage из Java отправит сообщение нескольким клиентам, каждый с другим токеном, которые совместно используют ключ канала? Кажется, это противоречит документации на странице developers.google.com/appengine/docs. /java/channel/, в котором говорится, что одновременно только один клиент может подключиться к каналу с использованием данного идентификатора клиента, поэтому приложение не может использовать идентификатор клиента для разветвления. Если получится, как вы говорите, будет здорово. Но я так не думаю. - person Chuck; 11.03.2013
comment
Насколько я знаю, описанный метод разветвления работает локально, но не в производстве. Вам нужно будет назначить разные ключи канала для разных клиентов и проходить через них, отправляя обновления каждому из них. - person Jon Newmuis; 11.03.2013

Я новичок в StackOverflow и не уверен, что этот вопрос все еще открыт, но если вы все еще ищете полный пример Java с использованием API канала Google, как ServerSide (Java), так и Client (Java), вы можете найти подробное описание I написал здесь: http://masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/

В нем изложено все, от создания канала (клиент и сервер), отправки сообщения по каналу (клиент и сервер), а также простой фреймворк, который клиенты Java могут использовать для взаимодействия с каналами. Мне тоже было трудно понять документацию Google и разобраться во всем этом. Надеюсь, эта информация все еще актуальна и полезна :-)

Полный исходный код и пример чата можно найти на GitHub: https://github.com/gvsumasl/jacc.

Вот пример кода, надеюсь, это поможет :-)


Создание канала на стороне клиента Java (с использованием ChannelAPI Framework: Jacc)

ChatListener chatListener = new ChatListener();
ChannelAPI channel = new ChannelAPI("http://localhost:8888", "key", chatListener);
channel.open();

Создание бокового канала Java Server:

public class ChatChannelServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {    
    String channelKey = req.getParameter("c");

    //Create a Channel using the 'channelKey' we received from the client
    ChannelService channelService = ChannelServiceFactory.getChannelService();
    String token = channelService.createChannel(channelKey);

    //Send the client the 'token' + the 'channelKey' this way the client can start using the new channel
    resp.setContentType("text/html");
    StringBuffer sb = new StringBuffer();
    sb.append("{ \"channelKey\":\"" + channelKey + "\",\"token\":\"" + token + "\"}");

    resp.getWriter().write(sb.toString());
  }
}

Отправка клиентских сообщений Java (с использованием ChannelAPI Framework: Jacc)

/***
* Sends your message on the open channel
* @param message
*/
public void sendMessage(String message){
try {
        channel.send(message, "/chat");
    } catch (IOException e) {
        System.out.println("Problem Sending the Message");
    }
}

Отправка сообщений на стороне сервера Java:

public class ChatServlet extends HttpServlet {
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String channelKey = req.getParameter("channelKey");
    String message = req.getParameter("message");

    //Send a message based on the 'channelKey' any channel with this key will receive the message
    ChannelService channelService = ChannelServiceFactory.getChannelService();
    channelService.sendMessage(new ChannelMessage(channelKey, message));
  }
}
person riptide464c    schedule 09.02.2012
comment
Я исправил это с помощью запроса на вытягивание. Надеюсь, возьмут. - person JohnyTex; 07.07.2015
comment
Под какой лицензией jacc? - person JohnyTex; 07.07.2015