Harici İnternet bağlantısına göre durumu dinamik olarak değiştirme - Tepki (çevrimdışı / çevrimiçi)


10

Internet bağlantısı kullanılabilirlik bayrağı içeren bir React bileşeni var. Kullanıcı arabirimi öğeleri, gerçek zamanlı duruma göre dinamik olarak değiştirilmelidir. Ayrıca, işlevler bayrağın değişikliklerinden farklı davranır.

Geçerli uygulamam, aralık ve güncellemeleri kullanarak Axios kullanarak uzak API'yi her saniyede yoklar. Ben asgari hesaplama maliyeti ile devlet 1 saniyelik hata kaldırmak için bu görevi yapmak için daha ayrıntılı ve verimli bir yol arıyorum. Yalnızca cihazın harici bir İnternet bağlantısı varsa çevrimiçi olarak kabul edilir

Mevcut uygulama:

class Container extends Component {
  constructor(props) {
    super(props)
    this.state = {
      isOnline: false
    };
    this.webAPI = new WebAPI(); //Axios wrapper
  }

  componentDidMount() {
    setInterval(() => {
      this.webAPI.poll(success => this.setState({ isOnline: success });
    }, 1000);
  }

  render() {
    return <ChildComponent isOnline={this.state.isOnline} />;
  }
}

Düzenlendi:

Harici İnternet bağlantısını algılayabilecek bir çözüm arıyor. Cihaz, harici bağlantısı olmayan bir LAN'a bağlanabilir. Yani, çevrimdışı olarak kabul edilir. Yalnızca aygıtın harici İnternet kaynaklarına erişimi varsa çevrimiçi olarak düşünebilirsiniz.


2
Çevrimdışı mı yoksa çevrimiçi mi olduğunuzu bilmeniz mi gerekiyor? veya hangi internet bağlantısı?
tudor.gergel

Evet. Temel olarak çevrimiçi veya çevrimdışı.
Nilanka Manoj

bir websocket bağlantısı gösterecek şekilde API'yi değiştirebilir misiniz?
yadejo

Yanıtlar:


2

Birinci yöntem: Eski tarayıcı API'sını kullanma - Navigator.onLine

Tarayıcının çevrimiçi durumunu döndürür. Özellik, gerçek anlamı çevrimiçi ve yanlış anlamı çevrimdışı olmak üzere bir boole değeri döndürür. Özellik, tarayıcının ağa bağlanma yeteneği değiştiğinde güncellemeler gönderir. Güncelleştirme, kullanıcı bağlantıları izlediğinde veya bir komut dosyası uzak sayfa istediğinde gerçekleşir. Örneğin, kullanıcılar İnternet bağlantısını kaybettikten kısa bir süre sonra bağlantıları tıkladığında özellik yanlış döndürmelidir.

Bileşen yaşam döngünüze ekleyebilirsiniz:

Chrome geliştirici araçlarını kullanarak aşağıdaki kodla oynayın - Ağ sekmesi altındaki "Çevrimiçi" yi "Çevrimdışı" olarak değiştirin.

class App extends React.PureComponent {
  state = { online: window.navigator.onLine }
  
  componentDidMount() {
    window.addEventListener('offline', this.handleNetworkChange);
    window.addEventListener('online', this.handleNetworkChange);
  }
  
  componentWillUnmount() {
    window.removeEventListener('offline', this.handleNetworkChange);
    window.removeEventListener('online', this.handleNetworkChange);
  }
  
  handleNetworkChange = () => {
    this.setState({ online: window.navigator.onLine });
  }
  
  render() {
    return (
      <div>
       { this.state.online ? 'you\'re online' : 'you\'re offline' }
      </div>
    );
  }
}

ReactDOM.render(
  <App />
, document.querySelector('#app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>


Ancak, bu istediğiniz şey olmadığını düşünüyorum, gerçek zamanlı bir bağlantı doğrulayıcı istediniz .

İkinci yöntem: İnternet bağlantısını kullanarak kontrol etme

Harici internet bağlantısı çalışıyorsa alabileceğiniz tek sağlam onay kullanmaktır. Soru, maliyeti en aza indirmek için hangi sunucuyu aramanız gerektiğidir?

İnternette bunun için birçok çözüm var, hızlı 204 durumuyla yanıt veren herhangi bir uç nokta mükemmel, örneğin:

  • Google sunucusuna çağrı yapıyor (savaşta en fazla test edilen (?))
  • önbelleğe alınmış JQuery komut dosyası bitiş noktasını çağırarak (sunucu kapalı olsa bile, bir bağlantınız olduğu sürece komut dosyasını almanız gerekir)
  • kararlı bir sunucudan resim getirmeyi deneyin (ör: önbelleğe almayı önlemek için https://ssl.gstatic.com/gb/images/v1_76783e20.png + tarih zaman damgası)

IMO, bu React uygulamasını bir sunucuda çalıştırıyorsanız, kendi sunucunuzu aramak en mantıklıdır /favicon.ico, bağlantıyı kontrol etmek için cihazınızı yüklemek için bir istek çağırabilirsiniz .

(Kendi sunucuyu aramanın) Bu fikir gibi birçok kütüphaneler tarafından uygulamaya konmuştur Offline, is-reachableve yaygın toplum genelinde kullanılmaktadır. Her şeyi kendiniz yazmak istemiyorsanız bunları kullanabilirsiniz. (Şahsen NPM paketinin is-reachablebasit olmasını seviyorum .)

Misal:

import React from 'react';
import isReachable from 'is-reachable';

const URL = 'google.com:443';
const EVERY_SECOND = 1000;

export default class App extends React.PureComponent {
  _isMounted = true;

  state = { online: false }

  componentDidMount() {
    setInterval(async () => {
      const online = await isReachable(URL);

      if (this._isMounted) {
        this.setState({ online });
      }
    }, EVERY_SECOND);
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  render() {
    return (
      <div>
       { this.state.online ? 'you\'re online' : 'you\'re offline' }
      </div>
    );
  }
}

Test Sunucusu Bağlantısını Düzenle

Şu anda sahip olduğunuz şeyin zaten iyi olduğuna inanıyorum, sadece doğru uç noktası çağırdığından emin olun.


Benzer SO soruları:



2

Özel bir kanca ayarlama

Çevrimiçi, çevrimdışı etkinliklerle bir kanca oluşturun. ardından bir durumu güncelleyin ve geri gönderin. Bu şekilde, bir içe aktarma ile uygulamanızın herhangi bir yerinde kullanabilirsiniz. Geri dönüş işleviyle temizlediğinizden emin olun. Bunu yapmazsanız, kanca montajı kullanan bir bileşen her defasında daha fazla olay dinleyicisi eklersiniz.

const onlineHook = () => {
  const {isOnline, setOnline} = React.useState();

  React.useEffect(() => {
    const goOnline = function(event){
      setOnline(true);
    });
    const goOffline = function(event){
      setOnline(false);
    });

    window.addEventListener('offline', goOffline);
    window.addEventListener('online', goOnline);

    return () => {
      window.removeEventListener('offline', goOffline);
      window.removeEventListener('online', goOnline);      
    }
  }, [])

  return isOnline
}

Bunu kullanmak için yukarıdaki kancayı içe aktarın ve böyle çağırın.

const isOnline = onlineHook(); // true if online, false if not


3
Firebase gibi soketli bir hizmet kullanıyorsanız, internet bağlantısını yakalayan yerleşik bir olay kullanabilirsiniz.
Joe Lloyd

önerilen yaklaşım için temel bir kod iskeleti sağlayabilir misiniz?
Nilanka Manoj

2

Tüm alt bileşenler arasında paylaşmak için bir bileşen oluşturabilirsiniz

Kullanılmış:

import React, { useState, useEffect } from "react";

export default function NetworkChecker() {

  const [networkStatus, setNetworkStatus] = useState(true)

  useEffect(() => {
    window.addEventListener('offline', (event) => {
      setNetworkStatus(false)
    });

    window.addEventListener('online', (event) => {
      setNetworkStatus(true)
    });

    return function cleanupListener() {
       window.removeEventListener('online',  setNetworkStatus(true))
       window.removeEventListener('offline', setNetworkStatus(false))
     }

  },[])

  if (networkStatus) {
    return <div className={"alert-success"}>Online</div>
  } else {
    return <div className={"alert-danger"}>Offline</div>
  }

}

Etkinlik dinleyicisini kaldırmayı mı unuttunuz?
gautamits
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.