Browser disconnection event offline and networking event online

Posted by zbert on Sat, 22 Jan 2022 10:28:20 +0100

How to deal with browser disconnection?

Good disconnection handling will make people very comfortable: lol's disconnection and reconnection, and the disconnection and reconnection of King's glory can ensure the continuation of the game

Bad disconnection handling or even not handling will lead to bugs: for example, there is a bug in the project I am working on. The business staff expressed great distress

Network problem has always been a problem worthy of attention.

For example, in the case of slow network, add loading to avoid repeated requests, use promise to process the return results of requests in sequence, or add some friendly upload progress tips, etc.

So have you ever thought about what to do when the network is disconnected? For example, the network is normal - > disconnected - > the network is normal.

In fact, I never thought about it until the test in the group detected a bug caused by network disconnection, which made me realize that there may be serious bugs in the case of network disconnection due to heavy dependence on the front end of network requests.

Therefore, I will record my handling of the system disconnection here to avoid bug s and ensure that users know that the network has been disconnected in time in the application

  • overview
  • Navigator used to detect whether the browser is connected to the network onLine
  • Navigator used to detect network conditions connection
  • Disconnection event "offline" and networking event "online"
  • Actual operation of network disconnection treatment project
    • Ideas and effects
    • Use of disconnection processing component
    • Details of disconnection processing components
    • find
  • reference material

overview

In order to build a "offline" web application, you need to know when the application is offline. We should not only know when to disconnect the network, but also know when the network will return to normal (online). The following two common situations can be broken down:

  1. You need to know when the user is online so that you can re sync with the server.
  2. You need to know when the user will be offline, so that you can send your unsolicited requests to the server after a period of time.

You can usually do this through online/offline events.

Navigator used to detect whether the browser is connected to the network onLine

navigator.onLine

  • true online
  • false offline

You can switch to offline through the online option of network to print navigator Online validation.

This property is updated when the browser cannot connect to the network. As defined in the specification:

The navigator.onLine attribute must return false if the user agent will not contact the network when the user follows links or when a script requests a remote page (or knows that such an attempt would fail)...

Navigator used to detect network conditions connection

How to automatically detect network conditions and switch definition when watching videos on youtube? Domestic video websites will also give a reminder of switching networks. How to detect it? In other words, is there any way to detect the network condition? Judge whether the current network is smooth, congested and busy? You can use navigator Connection. The attributes include effectiveType, rtt, downlink and change network event change. Inherits from the NetworkInformation API.

navigator.connection

Run console in the online state log(navigator.connection);

{
    onchange: null,
    effectiveType: "4g",
    rtt: 50,
    downlink: 2,
    saveData: false
}
Copy code

Via navigator Connection can determine online, fast 3g, slow 3g, and offline. The effective types in these four states are 4g, 3g, 2g, and 4g respectively (rtt and downlink are all 0).

What are rtt and downlink? What is NetworkInformation?

These are two parameters that reflect the network status. They are more concrete than type and can better reflect the real situation of the current network.

Common network conditions rtt and downlink table

Network statusrtt(ms)downlink(Mbit/s)
online1002.2
fast 3g6001.55
slow 3g21500.4
offline00

Note: rtt and downlink are not fixed values, but change in real time. When online, it may now be rtt 100ms, 2.2Mb/s, and the next second will become 125ms, 2.1Mb/s.

rtt

  • Estimated round trip time of connection
  • Unit: ms
  • The value is rounded to the nearest multiple of 25 milliseconds (that is, the value x% 25 = = 0, you can observe the common network conditions rtt and downlink table)
  • The smaller the value, the faster the network speed. time like ping
  • Available in Web Worker

downlink

  • Bandwidth estimate
  • The unit is Mbit/s (note that it is Mbit, not MByte.)
  • The value is also a multiple rounded to the nearest 25 bits / second (that is, the value x% 25 = = 0. You can observe the rtt and downlink tables of common network conditions)
  • Generally, the wider the width, the faster the speed, that is, more can be transmitted on the channel. Make complaints about the principle of communication.
  • The higher the value, the faster the network speed. Similar highways are generally wider than national highways.
  • Available in Web Worker

NetworkInformation API in Draft stage

Both rtt and downlink are the contents of this draft. In addition, there are downlinkMax, saveData, type and other attributes. For more information: NetworkInformation

How to detect network changes to respond?

NetworkInformation inherits from EventTarget and can respond by listening to change events.

For example, can you get changes in network conditions?

var connection = navigator.connection;
var type = connection.effectiveType;

function updateConnectionStatus() {
  console.log("Network status from " + type + " Switch to" + connection.effectiveType);
  type = connection.effectiveType;
}

connection.addEventListener('change', updateConnectionStatus);
Copy code

After listening for changes, we can play a Modal to remind the user, or a Notice to notify the user that the network has changed, or we can switch the definition automatically at a higher level (this should be difficult).

The concept of network information is introduced, just thinking of a role of throwing bricks and attracting jade. This fine-grained network condition detection can be realized in combination with specific requirements.

In this blog post, we only deal with network disconnection and network connection. Let's look at the network disconnection event "offline" and network connection event "online".

Disconnection event "offline" and networking event "online"

The browser has two events: "online" and "offline" These two events will be emitted by the < body > of the page when the browser switches between online mode and offline mode.

Events bubble in the following order: document body -> document -> window.

Events cannot be cancelled (developers cannot manually change the code to online or offline. Developers can use developer tools during development).

Several ways to register online and offline events

The most recommended combination is window+addEventListener.

  • Through window or document or document Body and addeventlistener (chrome 80 is only valid for window)
  • Is document or document Body Online or The online offline property sets a js function. (note that there will be compatibility problems when using window.online and window.online offline)
  • You can also register events through tags < body online = "onlinecb" onlinecb "></body>

example

<div id="status"></div>
<div id="log"></div>
Copy code
window.addEventListener('load', function() {
  var status = document.getElementById("status");
  var log = document.getElementById("log");

  function updateOnlineStatus(event) {
    var condition = navigator.onLine ? "online" : "offline";
    status.innerHTML = condition.toUpperCase();

    log.insertAdjacentHTML("beforeend", "Event: " + event.type + "; Status: " + condition);
  }

  window.addEventListener('online',  updateOnlineStatus);
  window.addEventListener('offline', updateOnlineStatus);
});
Copy code

insertAdjacentHTML is inserted near the tag node. You can see: insertAdjacentHTML of DOM advanced

Actual operation of network disconnection treatment project

The offline processing components can be encapsulated based on vue and react, and can be introduced on the required page.

Ideas and effects

As long as the network disconnection reminder + mask and online reminder mask can be achieved.

  • Listen to the offline and give a reminder and mask when the network is disconnected. Please check the network connection.
  • Listen to the online and connect to the network to give reminders and masks: the network is connected.

Use of disconnection processing component

<OfflineHandle
    offlineTitle = "Disconnection processing title"
    desc="Description of network disconnection treatment"
    onlineTitle="Networking reminder"
/>
Copy code

Vue components

Online demo: codesandbox.io/s/offline-h...

<!--OfflineHandle.vue-->
<template>
  <div v-if="mask" class="offline-mask">
    <h2 class="offline-mask-title">{{ offlineTitle }}</h2>

    <p class="offline-mask-desc">{{ desc }}</p>
  </div>
</template>

<script>
export default {
  name: "offline-handle",
  props: {
    offlineTitle: {
      type: String,
      default: "The network is disconnected. Please check the network connection.",
    },
    onlineTitle: {
      type: String,
      default: "Network connected",
    },
    desc: {
      type: String,
      default: "",
    },
    duration: {
      type: Number,
      default: 4.5,
    },
  },
  data() {
    return {
      mask: false,
    };
  },
  mounted() {
    window.addEventListener("offline", this.eventHandle);
    window.addEventListener("online", this.eventHandle);
    console.log(this.desc);
  },
  beforeDestroy() {
    window.removeEventListener("offline", this.eventHandle);
    window.removeEventListener("online", this.eventHandle);
  },
  methods: {
    eventHandle(event) {
      const type = event.type === "offline" ? "error" : "success";
      this.$Notice[type]({
        title: type === "error" ? this.offlineTitle : this.onlineTitle,
        desc: type === "error" ? this.desc : "",
        duration: this.duration,
      });
      setTimeout(() => {
        this.mask = event.type === "offline";
      }, 1500);
    },
  },
};
</script>

<style lang="css" scoped>
.offline-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  z-index: 9999;
  transition: position 2s;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.offline-mask-title {
  color: rgba(0, 0, 0, 0.8);
}
.offline-mask-desc {
  margin-top: 20px;
  color: red;
  font-weight: bold;
}
</style>
Copy code

React component

Online demo: codesandbox.io/s/offline-h...

// offlineHandle.js
import React, { useState, useEffect } from "react";
import { notification } from "antd";
import "antd/dist/antd.css";
import "./index.css";

const OfflineHandle = (props) => {
  const {
    offlineTitle = "The network is disconnected. Please check the network connection.",
    onlineTitle = "Network connected",
    desc,
    duration = 4.5
  } = props;
  const [mask, setMask] = useState(false);

  const eventHandler = (event) => {
    const type = event.type === "offline" ? "error" : "success";
    console.log(desc, "desc");
    openNotification({
      type,
      title: type === "error" ? offlineTitle : onlineTitle,
      desc: type === "error" ? desc : "",
      duration
    });
    setTimeout(() => {
      setMask(event.type === "offline");
    }, 1500);
  };

  const openNotification = ({ type, title, desc, duration }) => {
    notification[type]({
      message: title,
      description: desc,
      duration
    });
  };

  useEffect(() => {
    window.addEventListener("offline", eventHandler);
    window.addEventListener("online", eventHandler);
    return () => {
      window.removeEventListener("offline", eventHandler);
      window.removeEventListener("online", eventHandler);
    };
  }, []);

  const renderOfflineMask = () => {
    if (!mask) return null;
    return (
      <div className="offline-mask">
        <h2 className="offline-mask-title">{offlineTitle}</h2>

        <p className="offline-mask-desc">{desc}</p>
      </div>
    );
  };

  return <>{renderOfflineMask()}</>;
};

export default OfflineHandle;
Copy code

index. The CSS file is consistent with the content in the style tag of vue.

find

  • offline and online events: window is valid, document and document Invalid body setting

The project in hand only runs in Chrome browser. It takes effect only when offline and online are set for window. Operating environment: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"

  • Add 2s to position to avoid screen flashing

Topics: Javascript