How to reconnect signalR properly after disconnected - asp.net-mvc

In my angular6 website with ASP.NET server application ,
I want the singnalR client should always stay connected with Hub(Server). For that purpose started the connection on disconnected event with below code snap.
this.connection.start().done((data: any) => {
console.log('Now connected');
this.connectionId = this.connection.id;
this.connectionEstablished.emit(true);
this.connectionExists = true;
}).fail((error: any) => {
this.connectionEstablished.emit(false);
});
this.connection.reconnecting(() => {
this.tryingToReconnect = true;
});
this.connection.reconnected(() => {
this.tryingToReconnect = false;
});
this.connection.error((error: any) => {
this.initialize();
});
this.connection.disconnected(() => {
if (this.tryingToReconnect) {
setTimeout(() => {
this.initialize();
}, 5000);
}
});;
Because of that above code, signalr creates the problem such as
crashes the client browser and memory leaks in below cases such as,
If there is problem in client internet connection for some hours , that time singalr continuously tries to create the connection with hub. Because of internet problem , logging the connection error in browser console infinitely until the successful connection with hub
If i close the server, that time also singalR logging the connection error in browser console infinitely until the successful connection with hub
How to rectify the problems for signalr always stay connected with Hub?

I would create an incremental value and each reconnect time out would be increased and showing a retry now option, same way Gmail does, is a good practice and would solve both problems.

Related

Periodic sync not fired in service worker

I'm trying to use background periodic sync for my website. I'm using localhost and registering the periodicsync event at 1*1000 ms, but that doesn't fire at all.
I had a look at this demo, but even if I install the website as an app, it won't fire at all.
Using chrome 87.0.4280.66.
It works however if I manually trigger the periodic sync event from Application developer window.
The periodicsync event will only register correctly when the app is installed as a PWA in a 'most' webkit based browsers only
https://developer.mozilla.org/en-US/docs/Web/API/Web_Periodic_Background_Synchronization_API
The conditions as to whe this will actually fire is unclear and is dependent on some wooly factors such as the users engagement with the website.
That is why the perameter that can be set when registering for the periodic sync is minInterval
This block will help you to register for it successfully, I am, unfortunatly unclear on what the 'real world' scenarios in which the peridic sync will fire:
const status = await navigator.permissions.query({
// #ts-ignore
name: 'periodic-background-sync',
});
if (status.state === 'granted') {
navigator.serviceWorker.ready.then(async (sw: any) => {
await sw.periodicSync.register('periodicsync', {
minInterval: 1000,
});
})
.catch(error => {
console.error('[BackgroundSync] Error: ' + JSON.stringify(error, null, 2));
});
}
else {
console.error('[BackgroundSync] Does not have permission');
}
}

Workaround for missing "Web Push" on Safari for my PWA

I am developing a PWA that requires Push-Notifications. Sadly IOS/Safari does not support https://w3c.github.io/push-api/#pushmanager-interface for now, so I think i might have to wrap a native APP around in some way.
In Android (before their "Trusted Web Activities" was a thing) you could use a WebView to basically display a headless Chrome-View in your App. Whats the equivalent in IOS and how does the interaction between push-notifications and the Webapp (the browser need to jump to a specific page) work?
One more thing I need is integration with our companys Mobile Device Management, which is Microsoft Intune. Having integrated MDMs in Android in the past i Know that this might be a major pain in the a**, so i'm considering to build the wrapper myself, for maximum flexibility. Another option would be something like Ionic, not sure now.
This may not necessarily work in your situation, but I had the exact same issue with a PWA for Safari and I solved it by just using long polling. It will allow you to get around all of the limitations with Safari and I was able to redirect and load sections within our SPA.
async function subscribe() {
let response = await fetch("/subscribe");
if (response.status == 502) {
// Status 502 is a connection timeout error,
// may happen when the connection was pending for too long,
// and the remote server or a proxy closed it
// let's reconnect
await subscribe();
} else if (response.status != 200) {
// An error - let's show it
showMessage(response.statusText);
// Reconnect in one second
await new Promise(resolve => setTimeout(resolve, 1000));
await subscribe();
} else {
// Get and show the message
let message = await response.text();
showMessage(message);
// Call subscribe() again to get the next message
await subscribe();
}
}
subscribe();
https://javascript.info/long-polling

How to stop signalr connection from hanging everything on multiple open tabs?

I'm using SignalR 2.2.2 to send users messages from my backend. When a user is logged in, and if other conditions are met, their connection is added to a group with the user's userId on my message hub.
It works great, as long as they have 10 or fewer tabs/windows open. Any beyond that, they're stuck in "Loading..." indefinitely.
It seems to just be getting stuck on $.connection.hub.start();
I don't necessarily need to allow each user an infinite amount of signalr connections, but breaking the entire site for them on 10 open tabs is a problem.
I've tried catching or handling an error, but it still just hangs there.
$(function () {
if (loggedInUser != null)
{
var user = loggedInUser.UserId;
var messaging = $.connection.messageHub;
if (conditions) {
$.connection.hub.start().done(function () {
messaging.server.joinGroup(user);
});
}
}
});
I want to do at least one of the following:
-Just stop adding connections if a limit is reached
-Increase the limit of connections
-If limit is reached, start closing earlier connections
-Try to connect, and after a few seconds if it doesn't work, give up

Why browser loads service worker when going offline and cause "An unknown error occurred when fetching the script."?

I register the service worker with this code:
// If the browser supports serviceWorker, and we haven't registered any - we'll register our: sw.js ..
if ('serviceWorker' in navigator && !navigator.serviceWorker.controller) {
navigator.serviceWorker.register('/sw.js').then(function(registrationObj) {
console.log('Registration object: ', registrationObj);
}).catch(function(error) {
// serviceWorker registration failed ..
console.log('Registration failed with ' + error);
});
} else {
console.log('Service worker already registered. Skip registration.')
};
I see my assets appear in the app cache. Then I go to the Application tab in Chrome, choose Service Workers, click offline and refresh the page.
The page opens fine, but I get this in browser console:
http://www.screencast.com/t/1uodUTHM5ig
and this in the Service Worker debugger:
http://www.screencast.com/t/zmqHMi9RJ
Probably because you do not have service worker in cache (And quite naturally. It is not supposed to be cached in the first place.) so it falls back to standard http fetch process, and it fails as app is offline.
That error does not hinder anything and does not effect how your app works. It is just telling you that it has failed to fetch the script. And it was not suppose to success when the app is offline anyway.
Your service worker script probably structured like this;
event.respondWith(
caches.match(event.request).then(function (response) {
if (response) {
return response;
}
// request for service worker .js file falls here as it is not in the cache
// this fails of course since the app is offline
return fetch(event.request).then(function (response) {
return response;
});
})
);

Pusher auto reconnect when detecting errors / disconnect

Is there some way to reconnect to Pusher if any error or non-connected state is found?
Here's our connection code:
var pusher = new Pusher('<apikey>', {encrypted: true});
var state = pusher.connection.state;
pusher.connection.bind( 'error', function( err ) {
console.log(err);
});
pusher.connection.bind('state_change', function(states) {
// states = {previous: 'oldState', current: 'newState'}
console.log(states);
});
The Pusher JavaScript library automatically attempts reconnection. You don't need to add any code to support this.
I can't find this anywhere in the Pusher docs, but I know this for a fact as I worked for Pusher for 2 years.
You can test by going to http://test.pusher.com/ and disconnecting from the Internet and then reconnecting again. The logging will show it is auto-reconnecting.

Resources