Триггер Angular2 можно наблюдать в определенное время

Итак, сначала немного контекста. У меня есть приборная панель angular 2, она находится за логином и также имеет встроенный сигнализатор. Для запроса, отправленного через http-клиент angular, я могу использовать перехватчик URL-адресов, чтобы проверить, истек ли срок действия токена, и если да, то запросить новый токен из API. Это отлично работает для всех аутентифицированных вызовов, кроме signalr.

С помощью signalr при входе в систему мы устанавливаем соединение и отправляем токен носителя как часть строки запроса. Однако, поскольку signalr является отдельным, он не использует угловой http-клиент, и поэтому перехватчик URL-адресов не попадает. Я думал о разных способах справиться с этим, и для меня самым чистым было бы подписаться на наблюдаемое, которое срабатывает, когда истечет срок действия токена.

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

Спасибо за любую помощь в этом.


person Tony_89    schedule 02.12.2018    source источник


Ответы (2)


Я не знаю о signalr, но я могу дать решение для вашего требования.

Вы можете использовать timer из rxjs, это точно так же, как setTimeout(), но просто Observable.

Создайте объекты даты для expirationDate и еще одного за пять минут до истечения срока действия. Вычтите их, чтобы найти время, за которое Observable должен сработать.

Передайте time в миллисекундах таймеру, с помощью которого вы сможете оформить подписку. После завершения вызова API снова вызовите тот же метод, чтобы повторно инициализировать таймер.

timerSubs: Subscription;  // to cancel existing timer   
ngOnInit() {
    this.calculateTimeForTimer()
}

calculateTimeForTimer() {
    let expirationDate = new Date();
    expirationDate.setTime(expirationDate.getTime() + 10 * 1000); // 10 seconds from now.
    // in your case use your own duration/date of expiration
    let alertDate = new Date(expirationDate);
    alertDate.setTime(alertDate.getTime() - 5 * 1000); // 5 seconds before expiration
    // in your case subtract 5 minutes instead of 5 seconds
    let timeDuration = (expirationDate.getTime() - alertDate.getTime());
    this._startTimer(timeDuration);
}

private _startTimer(timeDuration) {
    if (this.timerSubs) {
        this.timerSubs.unsubscribe();
    }

    this.timerSubs = timer(timeDuration).subscribe((data) => {
      // make the API call, and then calculate appropriate duartion and call startTimer() again
      of("This is your new Token").pipe(delay(2000)).subscribe((apiData) => {
          console.log("Data from API", apiData);
          this.calculateTimeForTimer();
      })
    })
}

См. образец здесь, он имеет 10 секунд в качестве даты истечения срока действия с текущего времени. https://stackblitz.com/edit/angular-bhupgg

person Ashish Ranjan    schedule 02.12.2018
comment
Спасибо, как раз то, что мне было нужно. - person Tony_89; 02.12.2018

Этот наблюдатель сделал бы это

const tokenTimeout = timeout;
let currentTime = new Date();

return new Observable(observer => {

  while(tokenTimeout > currentTime) {
    currentTime = new Date();
  }

  observer.next();
  observer.complete();
});

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

person Woot    schedule 02.12.2018