我正在使用python API为GAE构建一个应用程序。 It is running here.这是一款多人游戏。我使用Channel API在玩家之间传达游戏状态。
但是在应用引擎中,不会调用频道的 onmessage 处理程序。调用 onopen 处理程序。 onerror 或 onclose 也不会被调用。奇怪的是,这在本地开发服务器中完美运行。
这样的事情是否可能在开发服务器上有效,但在应用程序引擎本身却无法使用?
如果有人可以查看我的应用程序的描述并帮助我弄清楚发生了什么,我真的很高兴。谢谢。
<script>
sendMessage = function(path, opt_param, opt_param2) {
path += '?g=' + state.game_key;
if (opt_param) {
path += '&' + opt_param;
}
if (opt_param2) {
path += '&' + opt_param2;
}
var xhr = new XMLHttpRequest();
xhr.open('POST', path, true);
xhr.send();
};
以上功能用于向服务器发出post请求。
onOpened = function() {
sendMessage('/resp');
console.log('channel opened');
};
以上是我想在第一次打开频道时调用的功能。我将帖子发送到'/ resp'地址。
onMessage = function(m) {
console.log('message received');
message = JSON.parse(m.data);
//do stuff with message here
};
我想在上面的函数中处理我从该请求得到的响应。
以下是onerror和onclose处理程序。
onError = function() {
console.log('error occured');
channel = new goog.appengine.Channel('{{ token }}');
socket = channel.open();
};
onClose = function() {
console.log('channel closed');
};
channel = new goog.appengine.Channel('{{ token }}');
socket = channel.open();
socket.onopen = onOpened;
socket.onmessage = onMessage;
socket.onclose = onClose;
socket.onerror = onError;
</script>
此脚本位于body标记的顶部。这在我的本地开发服务器中工作正常。但是在app引擎上,
调用onOpen函数
我可以在服务器日志中看到/ resp的请求
但onMessage从未被调用过。控制台中不存在收到的日志“消息”。
这是服务器端。
token = channel.create_channel(user.user_id() + game.user1.user_id() )
url = users.create_logout_url(self.request.uri)
template_values = {
'token' : token,
'id' : pid,
'game_key' : str(game.user1.user_id()),
'url': url
}
path = os.path.join(os.path.dirname(__file__), 'game.html')
self.response.out.write(template.render(path, template_values))
这是在'/ resp'请求的请求处理程序中。我的应用程序是一个多人纸牌游戏。我想通知其他玩家新玩家已连接。即使是新连接的播放器也会收到此消息。
class Responder(webapp2.RequestHandler):
def post(self):
user = users.get_current_user()
game = OmiGame.get_by_key_name(self.request.get('g'))
if game.user1:
channel.send_message(game.user1.user_id() + game.user1.user_id() , create_message('%s joined.' % user.nickname()))
if game.user2:
channel.send_message(game.user2.user_id() + game.user1.user_id() , create_message('%s joined.' % user.nickname()))
编辑:user1是创建游戏的用户。我希望通过添加user1的user_id和相关用户user_id来创建其他玩家的标记。这可能会出问题吗?
因此,当我在本地开发服务器上尝试这个时,我得到这些消息非常好。但是在GAE上没有调用onMessage。 This is my app.单击创建按钮时,将加载带有上述脚本的页面并显示“playernickname connected”。
答案 0 :(得分:3)
开发服务器和生产中的通道行为有些不同。在开发服务器上,通道客户端只是频繁地轮询http请求。在生产中,使用彗星式长轮询。
我怀疑在onOpened处理程序中进行XHR调用可能存在问题。至少在Chrome中,我看到渠道API使用的下一个talkgadget GET请求已被取消。
尝试在onMessage函数之外调用sendMessage('/ resp')。也许可以通过使用setTimeout将它排入队列,以便在您返回后稍后调用它。