我正在尝试学习GAE的通道API(使用Java),但我无法弄清楚从哪里开始。
我浏览了Channel API Overview (Java)但是为了简洁起见,那里发布的代码并不完整。
由于我是新手,如果有完整的示例代码,那将非常有用。
谢谢, Shrey
答案 0 :(得分:33)
您链接到的频道API概述中的代码非常完整,只是在整个地方。我承认,一旦你理解了它,我觉得它比它们看起来更简单,但我很高兴他们在提供太多信息方面犯了错误。
在没有无关信息的情况下,为此提供完整的解决方案有点困难,因为您使用Channel API的一些方法有点依赖于您现有的应用程序的基础架构。出于这个原因,我试图详细说明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文档通过从Java servlet提供HTML并调用index.replaceAll("\\{\\{ token \\}\\}", token)
来完成此操作。
这是如何工作的,他们已经完成了将文字字符串{{ token }}
放在他们的JavaScript代码中(正如您将在下面看到的那样),因此无论JavaScript代码中出现{{ token }}
,它都会由上面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>
他们删除了有关如何从服务器上的文件中读取此内容的详细信息,但同样,您可以以您喜欢的任何方式执行此操作。您也可以在JavaServlet中使用resp.getWriter().print(index)
逐字打印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!");
}
我仍然建议将它们分成不同的功能,以便您可以更轻松地对它们进行扩展以进行游戏并解决问题。有关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();
};
此处,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!"));
上面的channelService.sendMessage(...)
调用是实际发送消息的内容,因此可能会被您在上一节中定义的onMessage
函数接收。
我希望这个答案是完整的(并且就此而言,正确)足以帮助您入门。他们放在文档中的大部分内容(以及我的代码)都可以复制和粘贴,只需要进行一些小的调整。
答案 1 :(得分: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();
Java Server Side Channel Creation:
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框架: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));
}
}