1

我正在使用 python API 为 GAE 构建一个应用程序。它在这里运行。这是一款多人游戏。我使用 Channel API 在玩家之间传达游戏状态。

但在应用引擎中,不会调用通道的onmessage处理程序。调用 onopen处理程序。onerroronclose也不会被调用。奇怪的是这在本地开发服务器中完美运行。

有没有可能这样的事情可以在开发服务器上运行,但不能在应用程序引擎本身上运行?

如果有人可以查看我的应用程序的以下描述并帮助我弄清楚发生了什么,我会非常高兴。谢谢你。

我调查了这个这个问题,但我没有犯过这些错误。

<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 标记的顶部。这在我的本地开发服务器中运行良好。但是在应用引擎上,调用了
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 没有被调用。这是我的应用程序。当单击创建按钮时,加载了上面脚本的页面并应显示“已连接玩家昵称”。

4

1 回答 1

3

开发服务器和生产服务器上的通道行为有些不同。在开发服务器上,通道客户端只是频繁地轮询 http 请求。在生产中,使用彗星式长轮询。

我怀疑在 onOpened 处理程序中进行 XHR 调用可能存在问题。至少在 Chrome 中,我看到通道 API 使用的下一个talkgadget GET 请求被取消。

尝试在 onMessage 函数之外调用 sendMessage('/resp') 。也许通过使用 setTimeout 将其排入队列以运行,以便稍后在您返回后调用它。

于 2013-04-17T05:16:30.170 回答