joicomponents
Version:
Design patterns to build native web components
115 lines (90 loc) • 3.67 kB
Markdown
# Mixin: LieFi
Todo, this could be converted to a ComposedEvent that employs listeners that poll for extra
information.
Todo. This should probably not be a mixin, but an element or a function..
A typical problem for web apps working on a 3g/4g connection, is that the browser is registered as online,
but the web connection is nonresponsive. We have a LieFi situation.
`LieFiMixin` listens to when an element is `online` and `offline`.
But, when the browser is registered as `online`, `LieFiMixin` also polls/pings a server
to see:
* if the ping can be completed and
* how long the ping takes to complete.
Based on this polling, the `LieFiMixin` makes its own assumption about whether or not it *really is online*.
The `LieFiMixin` stores this value in its own .isOnline property.
The `LieFiMixin` uses several StaticSettings to control this polling:
```javascript
return {
server: "serverAddress", //defaults to "https://google.com"
threshold: 200, //ms response should be recevied within this timespan
variance: 50 //% how much the response time is allowed to vary
}
```
liefiCallback() has the following signature
```javascript
function liefiCallback(online, timeSinceLastConnection, varianceOf5LastPolls) {
}
```
## Mixin: LieFi
The LieFiMixin remembers how long it was since the last connection.
If the connection changes more often than once per 5 seconds,
then it will not alert the user that it is connected, but that it has a weak connection.
The LieFiMixin also actively polls a micro network resource every 10seconds
to see if it can get it if the network is reportedly on.
How best to do this I don't know.
Heavy user of [MixinSingleton] pattern.
```javascript
const objs = [];
function triggerCallbacks(msg){
for(let obj of objs){
if (obj.isConnected)
obj.onlineOfflineCallback(msg);
}
}
const gettingOn = [];
if (window.isOnline)
gettingOn.push(performance.now());
function con(){
gettingOn.push(performance.now());
if (gettingOn.length === 1)
triggerCallbacks("on");
let last = gettingOn[gettingOn.length-1];
let secondToLast = gettingOn[gettingOn.length-2];
if ((last-secondToLast)<5000)
triggerCallbacks("flaky network");
else
triggerCallbacks("on");
}
function disCon(){
for(let obj of objs){
if (obj.isConnected)
obj.onlineOfflineCallback();
}
}
function pollNetwork(){
//try to get a very small network resource.
// If it takes more than 10 seconds, then alert the callback that it takes too long.
// triggerCallbacks("liefi network" + duration);
}
window.addEventListener("online", con);
window.addEventListener("offline", discon);
window.setInterval(pollNetwork, 10000);
function LieFiMixin(Base){
return class LieFiMixin extends Base {
connectedCallback(){
super.connectedCallback && super.connectedCallback();
objs.push(this);
}
disconnectedCallback(){
super.connectedCallback && super.connectedCallback();
objs.remove(this); //todo does not exist of course
}
};
}
```
The liefiCallback(online, timeSinceLastConnection, varianceOf5LastPolls) tells the element:
* triggers every time the internal liefi online value changes
## TODO
1. maybe this should not be a mixin, but a global event `liefi` that is dispatched on the window and
that all elements can listen to? yes, this is likely true. I see no real use to keep this as a mixin.
The only point of having this as a mixin would be to have different settings for when something is online/offline
depending on different element types, and not the app as a whole.. But I don't really see the use case here.