我阅读了 Channel API Overview (Java),但那里发布的代码出于简洁起见并不完整。
由于我是新手,如果有完整的示例代码将非常有帮助。
谢谢, Shrey
您提供的Channel API Overview中的代码非常完整,只是有些混乱。我必须承认,一旦您理解了它,我觉得它比他们描述的要简单得多,但我很高兴他们在提供太多信息方面出错。
要完整地解决这个问题有点困难,因为您将如何使用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)
来完成此操作。
其原理是在JavaScript代码中放置了文字字符串{{ token }}
(如下所示),因此无论JavaScript代码中的哪个位置出现{{ token }}
,它都将被上面的channelService.createChannel(...)
调用生成的实际令牌替换。请注意,您不必在以这种方式提供的客户端代码中注入令牌,但这是一个很好的起点,因为这就是他们所做的(并记录下来的)。
既然您已经在JavaScript中注入了令牌,您需要将带有通道令牌的代码传递给客户端。(请注意,正如上面所述,您也可以只将令牌传递给客户端,并以此方式创建通道)。他们的代码如下:
<body>
<script></script>
</body>
他们没有详细说明如何从服务器的文件中读取内容,但是你可以按照自己喜欢的任何方式进行操作。你也可以在 JavaServlet 中使用 resp.getWriter().print(index)
直接打印字符串,其中index
是保存上述 HTML/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参考。
你需要建立一种机制来从客户端到服务器获取要发送的数据。再次强调,您希望如何执行此操作并不重要。 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
。这是他们为其示例井字棋应用程序构建的所有基础设施,不是 Channel API 功能的关键;就像我说的,您可以以任何希望的方式进行此调用。
path
是到您的servlet的路径(您需要在web.xml文件中设置),该servlet应处理消息的发送和接收(请参见以下部分)。
在客户端向服务器发送消息后,您需要一个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
函数接收。
我希望这个答案足够完整(也正确)以帮助您入门。大部分文档中提到的内容(以及我的代码)都可以复制粘贴,只需要进行少量修改。
ChatListener chatListener = new ChatListener();
ChannelAPI channel = new ChannelAPI("http://localhost:8888", "key", chatListener);
channel.open();
在Java中创建服务器端通道:
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));
}
}