Up tonight, I need to fix a problem that seems to have popped up recently with my (fab) game in Chrome. Specifically, the comet
<iframe>
seems to be closing after only a minute. I am reasonably sure that this started in a recent Chrome build, but regardless of the cause, I need to make sure that the <iframe>
stays open.Happily, this is pretty easy to do in my fab.js backend:
function keepalive(id) {If a player's ID is in the list of players, call the downstream (closer to the browser) listener with a NOP body. Then, wait another 30 seconds and keepalive again. I then call the
if (players[id]) {
puts("keepalive: " + id);
players[id].listener({body: '<script type="text/javascript">"12345789 "</script>' + "\n"});
setTimeout(function(){keepalive(id);}, 30*1000);
}
}
keepalive
function for the first time when the new player is added in the broadcast_new
app:function broadcast_new (app) {That is a good place to call
return function () {
var out = this;
var downstream;
return app.call( function listener(obj) {
if (obj && obj.body && obj.body.id) {
for (var id in players) {
out({body: comet_walk_player(JSON.stringify(players[id].status))});
}
var new_id = obj.body.id;
puts("adding: " + new_id);
players[new_id] = {status: obj.body, listener: out};
idle_watch(new_id);
setTimeout(function(){keepalive(new_id);}, 30*1000);
puts("broadcasting about: " + new_id);
broadcast(comet_walk_player(JSON.stringify(obj.body)));
}
else {
downstream = out(obj);
}
return listener;
});
};
}
keepalive
for the first time because I am sure that the new player in the game is already in the players
list. (I do make a TODO to clean-up that app—it's getting a tad large) That keeps the comet connection open seemingly indefinitely—or at least until the idle_watch
kicks the player out of the room.Minor Bug Fix
Much to my chagrin, I found that chat was no longer working in my (fab) game when I tried to demo it at Bohconf today. I take a little time to investigate that and fix it as well. The fix was a simple matter of removing code that seemed to serve no purpose:
Player.prototype.notify = function(evt) {It is beyond me why, when sending a chat event, I would need to stop the player walking through the room, walk them to the current x-y coordinate, then notify the fab.js backend that the player moved to the coordinates of an event that does not have coordinates. Craziness. What's worse, I was quite pleased with myself when I did it, though didn't say why. Tracer bullets do not prevent all mistakes. Ah well, removing those lines fixes chat and all's well that ends well.
switch(evt.type) {
case "click":
this.stop();
this.walk_to(evt.x, evt.y);
this.notify_server('move', {id:this.id, x:evt.x, y:evt.y});
break;
case "message":
this.stop();
this.walk_to(this.x, this.y);
this.notify_server('move', {id:this.id, x:evt.x, y:evt.y});
this.notify_server('chat', {id:this.id, say:evt.value});
break;
default:
console.debug("[notify] type: " + evt.type + " value: " + evt.value);
}
};
Up tomorrow, my code could use a bit of refactoring, but I'm itching to play with web sockets. Which urge will win out?
Day #127
No comments:
Post a Comment