So, in a nutshell, I’ve been spending the last week trying to fix a weird problem with safari, using a meteor site I’m building, and am beginning to think I am losing my mind.
Basically, I want to have Meteor.call()s rapidly fire in order to sync state in an action based game. My code, stripped of fluff, is the following:
if (Meteor.isClient) {
// this == window / global
this.Physics = {}
Physics.counter = 0;
Physics.updating = false;
Physics.onUpdate = function(err, res){
if(err) { alert(err); }
else if (res.data == "test") {
document.getElementById("counter").innerHTML = ++this.counter;
this.updating = false;
} else {
document.getElementById("counter").innerHTML = "WTF?";
}
}
Physics.onUpdate = Physics.onUpdate.bind(Physics);
Physics.clientUpdate = function(){
if(!this.updating){
this.updating = true;
Meteor.call("update", {data: "test"}, Physics.onUpdate);
}
}
Template.test.onRendered(function(){
AnimationLoop();
})
AnimationLoop = function(){
Physics.clientUpdate();
requestAnimationFrame(AnimationLoop);
}
}
if (Meteor.isServer) {
Meteor.methods({
update: function(data) { return data; }
})
}
With an accompanying html file that consists of:
<head>
<title>call_test</title>
</head>
<body>
{{> test}}
</body>
<template name="test">
<p>You've hit the server <span id="counter">0</span> times.</p>
</template>
The expected behaviour is that on each animation frame, if there is not already an update in transit, fire a Meteor.call().
Now, as for the problem. On all browsers I’ve tested, this works absolutely fine, except for Safari… On Safari, it is ok for about ~150 iterations, but then just flat stops working. trying to manually kickstart it with retries does not work, and neither does adding fancy decorations like setTimeout()s.
The problem also exists on mobile safari (iOS) which is one of the primary deployment targets (using cordova) so this is a brutal breaker bug.
And here is the real kicker, if you open the debug menu and show the error console… the problem goes away and it works as expected. (also, when phone is hooked up to debug, the problem also goes away!)
I’m at my wits end and really could use a little bit of help figuring out what’s going on, and desperately am in need for some kind of workaround to get rapid fire Meteor.call()s working again.
Ideas? Suggestions? Solutions!? Thanks so much in advance for any help.
For the time being I have the test code above running at
http://abc.lambpop.com