We’re adding “Disconnected From Server” and “Reconnected To Server” notifications in our Meteor app. I love the built-in server connection API that Meteor has but I’m a bit puzzled by the way the Meteor.status()
is working with autorun
and the browser.
We have the following simple code that works pretty much as expected. The notification functions are our own. They all work as expected:
instance.autorun(function() {
const meteorStatus = Meteor.status();
const connected = meteorStatus.connected;
const status = meteorStatus.status;
// If the connection is lost and Meteor isn't trying to connect, whether on the initial load or after disconnecting,
// show the notification.
if(!connected && status != "connecting") {
// If disconnectedNotification hasn't been assigned yet, create a permanent notification and assign a reference to
// it. We need this because Meteor will attempt to reconnect several times if the connection is lost due to the
// server going down, losing an internet connection, etc, and we don't want to duplicate the notification.
if(!instance.disconnectedNotification)
instance.disconnectedNotification = createPermanentNotification("info", "Browser Disconnected", "You're currently offline. Try refreshing the page or checking your Internet connection.");
// Create a session variable so when the user refreshes, they'll see the reconnected notification. Use a persistent
// var so that it isn't wiped away by the refresh.
Session.setPersistent("showReconnectNotification", true);
}
// Once the browser connects to the server, check if the disconnectedNotification var or showReconnectNotification
// Session var have been assigned.
else if(connected && (instance.disconnectedNotification || Session.get("showReconnectNotification"))) {
// If the notification has been created, call .remove() on the notification to hide it. Use an optional chain here
// because the notification won't exist if this is firing after a refresh.
instance.disconnectedNotification?.remove();
// Remove disconnectedNotification to prevent this from firing again.
delete instance.disconnectedNotification;
// Display a temporary reconnected notification. No need to assign it because it's a temporary one.
createNotification("success", "Connection Restored", "Your browser has reconnected to the application.");
// Clear out the showReconnectNotification Session variable.
Session.clear("showReconnectNotification");
}
});
When I refresh the browser while a connection is working, no notifications are shown. Which is working as expected. We don’t want any notifications about connection if the user willingly refreshes their browser while their connection is good.
However, the problem, is if I close the browser and then re-open it, the Connected Restored notification always displays on reopening the browser window. After much debugging, this is because as the window closes, the first block of the autorun
where Session.setPersistent("showReconnectNotification", true)
is called always runs. showReconnectNotification
is always set to true
when closing. However, when refreshing, it doesn’t get set to true
as that block never gets called.
I find this kind of strange because when testing and trying to figure this out, there’s pretty much no way to detect the difference between a browser refresh and a browser close. And there’s a lot of hacky things people try to figure this out.
I’m not sure how Meteor is detecting the difference when I do a refresh and/or doing two different things. Unless it’s as simple as the Meteor.status().connected
never going to false
on a refresh. But it seems like this should happen, for however briefly, the same way it does on a close.
Anyone have any experience with this? For now, I’ve added a Date()
call in the mix to not show the Connected Restored notification after a certain length of time. Because as is, they’ll always see this notification upon re-opening a browser to the app after closing down.