HttpClient & Rxjs - PullRequest
       12

HttpClient & Rxjs

0 голосов
/ 19 февраля 2019

Я работаю над случаем, когда во время сетевого подключения у нас иногда может быть ограниченное подключение к Интернету, когда мы не можем получить ответ от сервера или не получен ответ как HttpError.Настоящим я пытаюсь пинговать URL каждую секунду, чтобы проверить, получаем ли мы ответ или нет, для этого

Я пытаюсь этот код, это нормально работает в онлайн-методе, но когда я переворачиваю свой Интернетне возвращает мне ложное значение.

fetch-data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Posts } from './posts';
import { Observable, interval, throwError, of } from 'rxjs';
import { take, exhaustMap, map, retryWhen, retry, catchError, tap, mapTo, } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class FetchDataService {

  public url = 'https://jsonplaceholder.typicode.com/posts';

  constructor(private _httpClient: HttpClient) { }

  getData() {
    const ob = interval(1000);
    return ob.pipe(
      exhaustMap(_ => {
        return this._httpClient.get<Posts[]>(this.url, { observe: 'response' });
      }),
      map(val => {
        if (val.status === 200)
          return true;
        throw val;
      }),
      retryWhen(errors => {
        return errors.pipe(map(val => {
          if (val.status === 0)
            return false;
        }))
      })
    );
  }


  // private handleError(error: HttpErrorResponse) {
  //   if (error.error instanceof ErrorEvent) {
  //     // A client-side or network error occurred. Handle it accordingly.
  //     console.error('An error occurred:', error.error.message);
  //   } else {
  //     // The backend returned an unsuccessful response code.
  //     // The response body may contain clues as to what went wrong,
  //     console.error(
  //       `Backend returned code ${error.status}, ` +
  //       `body was: ${error.error}`);
  //     if (error.status !== 200)
  //       return of(false);
  //   }
  //   // return an observable with a user-facing error message
  //   return throwError(
  //     'Something bad happened; please try again later.');

  // };

}

pulldata.component.html

import { Component, OnInit } from '@angular/core';
import { FetchDataService } from '../fetch-data.service';
import { Observable } from 'rxjs';
import { Posts } from '../posts';

@Component({
  selector: 'app-pulldata',
  templateUrl: './pulldata.component.html',
  styleUrls: ['./pulldata.component.css']
})
export class PulldataComponent implements OnInit {

  public data;
  public error = '';

  constructor(private _fecthDataServe: FetchDataService) { }

  ngOnInit() {
    this._fecthDataServe.getData().subscribe(val => {
      this.data = val;
      console.log(this.data);
    });

  }

}

Что было бы лучшим решением для проверки интернет-соединения таким образом?

1 Ответ

0 голосов
/ 19 февраля 2019

Мое личное предпочтение было бы не делать это с HTTP из-за перегрузки данных.Каждый HTTP-запрос будет содержать данные cookie и другие заголовки, которые часто бесполезны в подобных сценариях.

Можно ли использовать веб-сокеты ?С их помощью вы можете открыть соединение с сервером, которое, в отличие от HTTP, не должно закрываться.Это может остаться открытым навсегда.И вы можете подписаться на события, чтобы получать уведомления о потере соединения.Веб-сокеты также имеют дополнительное преимущество, заключающееся в том, что это новый протокол на основе TCP, а не HTTP, что приводит к гораздо меньшему количеству сетевых данных, которые необходимо отправлять.

let socket = new WebSocket('wss://yourserver/socket...');
socket.addEventListener('open', () => console.log('connection has been opened'));
socket.addEventListener('close', () => console.log('connection has been closed'));

В вашей ситуации вы также можете захотетьпроверить переподключение WebSocket , которое переподключается, когда соединение обрывается.Конечно, вы также можете написать эту небольшую оболочку самостоятельно.

Кроме того, что может быть даже более простым решением.Вы можете подписаться на online / offline события на объекте window: Подробнее о MDN

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

    // ...do something with the new status
}

window.addEventListener('online',  updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);

Оба эти решения должны легко оборачиваться в службе Angular, но дайте мне знать, если это сработает и / или эти варианты для вас.

...