Google App Engine渠道API

Shr*_*rey 7 java google-app-engine channel-api

我正在尝试学习GAE的通道API(使用Java),但我无法弄清楚从哪里开始.

我浏览了Channel API Overview(Java),但为了简洁起见,那里发布的代码并不完整.

因为我是新手,如果有完整的示例代码,那将非常有用.

谢谢,Shrey

Jon*_*uis 33

您链接到的渠道API概述中的代码非常完整,只是到处都是.我承认,一旦你理解了它,我觉得它比它们看起来更简单,但我很高兴他们在提供太多信息方面犯了错误.

如果没有无关的信息,就很难为此提供完整的解决方案,因为您使用Channel API的方式有点依赖于现有应用程序的基础架构.出于这个原因,我试图详细说明AppEngine文档提供的内容,以便您可以更好地理解.如果您有任何问题,评论将允许您提出具体问题.

首先,一点词汇:

  • 频道消息:您希望发送给客户端的消息(可能是您首先使用Channel API的原因).
  • 通道键:用户唯一的字符串以及用户尝试发送消息的范围.
  • 频道令牌:任何客户端都独有的字符串.每个客户每2小时1个通道令牌.
  • 频道服务: 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);
Run Code Online (Sandbox Code Playgroud)

获得令牌后,您只需要一些方法将其转换为客户端代码.您链接到的AppEngine文档通过从Java servlet提供HTML并调用来实现此目的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>
Run Code Online (Sandbox Code Playgroud)

他们删除了有关如何从服务器上的文件中读取此内容的详细信息,但同样,您可以以您喜欢的任何方式执行此操作.您也可以resp.getWriter().print(index)在JavaServlet中逐字打印String ,其中index是一个存储上面列出的HTML/JavaScript内容的String.就像我最初所说的那样,很多东西都取决于你最适合你应用程序现有基础架构的东西.

他们打算为你定义自己的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!");
}
Run Code Online (Sandbox Code Playgroud)

我仍然建议将它们分成不同的功能,这样你就可以更容易地扩展它们来玩耍并解决问题.有关JavaScript API的更多详细信息,请参阅Channel API JavaScript Reference.


您需要建立一种机制来获取要从客户端发送到服务器的数据.再一次,你希望如何做到这一点并不重要.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();
};
Run Code Online (Sandbox Code Playgroud)

这里,opt_param只是格式中的一串可选参数x=1&y=2&z=3.这是他们为样本Tic-Tac-Toe应用程序构建的所有基础架构,对于Channel API的功能并不重要; 就像我说的,你可以随心所欲地打这个电话.

path 是您应该处理消息发送和接收的servlet的路径(您需要在web.xml文件中设置)(请参阅下一节).


将消息从客户端发送到服务器后,您将需要一个可以使用相同通道密钥向所有客户端发送更新的servlet .

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!"));
Run Code Online (Sandbox Code Playgroud)

channelService.sendMessage(...)上面的调用是实际发送消息的内容,因此它可能由onMessage您在上一节中定义的函数接收.


我希望这个答案是完整的(并且就此而言,正确)足以帮助您开始.他们放在文档中的大部分内容(以及我的代码)都可以复制和粘贴,只需稍加调整即可.

  • 这个答案值得某种奖励:) (5认同)

小智 13

我是StackOverflow的新手,我不确定这个问题是否仍然存在,但是如果您仍在寻找使用Google的Channel API,ServerSide(Java)和Client(Java)的完整Java示例,您可以找到详细的说明我已经在这里写了:http://masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/

它规定了创建通道(客户端和服务器),在通道(客户端和服务器)上发送消息以及Java客户端可用于与通道交互的简单框架等所有内容.我也很难理解Google的文档并理解这一切.我希望这些信息仍然相关且有用:-)

完整的源代码和聊天示例可以在GitHub上找到:https://github.com/gvsumasl/jacc

这是一些示例代码,我希望这会有所帮助:-)


Java客户端通道创建(使用ChannelAPI框架:Jacc)

ChatListener chatListener = new ChatListener();
ChannelAPI channel = new ChannelAPI("http://localhost:8888", "key", chatListener);
channel.open();
Run Code Online (Sandbox Code Playgroud)

Java Server Side Channel创建:

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());
  }
}
Run Code Online (Sandbox Code Playgroud)

Java客户端消息发送(使用ChannelAPI框架: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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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));
  }
}
Run Code Online (Sandbox Code Playgroud)