实施Ionic/Angular的会话超时服务,并在每次新用户交互时重置计时器 [英] Implementing Session Timeout service for Ionic/Angular, with Timer Reset with each new user interaction

查看:40
本文介绍了实施Ionic/Angular的会话超时服务,并在每次新用户交互时重置计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试适应为会话超时创建的一些代码.每当用户与该功能进行交互时,我都想重置计时器以再次开始递减计数.我很难弄清楚如何向此示例

I'm trying to adapt some code I've created for a session timeout. Whenever a user interacts with the function, I want to reset the timer to start counting down again. I'm having difficulty working out how to inject similar code to this example

C#代码-我正在尝试集成:

C# code - I'm trying to integrate:

var update = new Subject<bool>();
var res =
    update
        .Select(x => Observable.Interval(TimeSpan.FromSeconds(10.0)))
        .Switch();
res
    .Subscribe(_ => Console.WriteLine("Status sent."));
update.OnNext(true);


res
    .Subscribe(_ =>
    {
        update.OnNext(true);
        Console.WriteLine("Status sent.");
    });


据我所知,RxJS库的C#风格的Typescript RxJS等效项以及我的变量名映射是:


From what I can tell the Typescript RxJS equivalents of C# flavour of the RxJS library and my variable name mapping are:

C#/示例打字稿/我的
更新resetManager
.Select .map (来自此处-(请参见标签标题)
.OnNext .next
.interval .timer

C#/example Typescript/mine
update resetManager
.Select .map (from here - (see tab title))
.OnNext .next
.Interval .timer

我当时想我可以插入一个do并将其链接到resetManager,但是由于一个是布尔值,另一个是AuthState,我似乎遇到了麻烦.

I was thinking I could insert a do and chain the resetManager - but since one is a boolean and the other is AuthState I seem to be running into difficulties.

我想知道RxJS专家是否可以提供建议.干杯.

import { Injectable }           from '@angular/core';
import { Observable }           from 'rxjs/Observable';
import { BehaviorSubject }      from 'rxjs/BehaviorSubject';
import                               'rxjs/add/operator/map';
import                               'rxjs/add/operator/filter';
import                               'rxjs/add/Observable/timer';
import                               'rxjs/add/operator/do';
import                               'rxjs/add/operator/switch';
@Injectable()
export class AuthService {
  private authState:    AuthState;
  private authManager:  BehaviorSubject<AuthState>;
  public  authChange$:  Observable<AuthState>;
  private resetManager: Subject<boolean>;
  constructor() {
    this.authManager = new BehaviorSubject(AuthState.LOGGED_OUT);
    this.authChange$ = this.authManager.asObservable();
    this.authChange$
      .filter((authState:AuthState) => authState === AuthState.LOGGED_IN)
      .map(   (authState:AuthState) => Observable.timer(SESSION_TIMEOUT))
      .do(    () => 
        console.log('Logged In. Session Timout counting down from now'))
      .switch()
      .subscribe( () => {console.log('Timer ended: Logging out')
                         this.logout();
                        });
  }

  login() {
    this.setAuthState(AuthState.LOGGED_IN);
  }
  logout() {
    this.setAuthState(AuthState.LOGGED_OUT);
  }

  resetSessionTimer() {
    this.resetManager.next(true);
  } 

  emitAuthState():void {
    this.authManager.next(this.authState);
  }

  private setAuthState(newAuthState:AuthState):void {
    console.log('AuthService: setAuthState: ', 
        AuthState[newAuthState.toString()]);
    if (newAuthState != this.authState) {
      this.authState = newAuthState;
      this.emitAuthState();
    }
  }

export enum AuthState {
  LOGGED_IN,
  LOGGED_OUT
}

const SESSION_TIMEOUT = 5000;

推荐答案

我终于弄清楚了该怎么做...

I finally worked out how to do this...

import { Events }               from 'ionic-angular';
import { Observable }           from 'rxjs/Observable';
import { Subscription }         from 'rxjs/Subscription';
import                               'rxjs/add/observable/interval';
import                               'rxjs/add/operator/mapTo';
import                               'rxjs/add/observable/defer';
import                               'rxjs/add/observable/of';
import                               'rxjs/add/operator/merge';
import                               'rxjs/add/operator/scan';
import                               'rxjs/add/operator/filter';
import                               'rxjs/add/operator/switchMap';
import { BehaviorSubject }      from 'rxjs/BehaviorSubject';

export  enum AuthState {
  LOGGED_IN,
  LOGGED_OUT
}

const SESSION_TIMEOUT = 10; // seconds

export class AuthService {
  private timer:         number;
  private tick$:         Observable<number>;
  private countDown$:    Observable<number>;
  private subscriptions:Subscription[];

  constructor(
    private events:Events
  ) {
    this.tick$ =Observable.interval(1000).mapTo(-1);
    this.countDown$ = Observable
      .defer(() => Observable.of(this.timer))
      .merge(this.tick$)
      .scan((acc,curr) => acc + curr)
    this.events.subscribe(RESET_COUNTDOWN, (action:string) => {
      this.resetSessionTimer(action);
    });
  }

  beginCountDown() {
    let sub:Subscription;
    while (this.subscriptions.length > 0) {
      sub = this.subscriptions.pop();
      sub.unsubscribe();
    };
    this.timer = SESSION_TIMEOUT;
    sub = this.countDown$
      .filter(timer => timer >= 0)
      .subscribe(timer => 
        {this.timer = timer;
         if (this.timer === 1) {
           this.logout();
         }
         console.log(this.timer);
        });
    this.subscriptions.push(sub);
  }

  resetSessionTimer(action:string) {
    console.log('AuthService: resetSessionTimer(): ' + action);
    this.beginCountDown();
  } 

  emitAuthState():void {
    this.authManager.next(this.authState);
  }

  private setAuthState(newAuthState:AuthState):void {
    if (newAuthState != this.authState) {
      this.authState = newAuthState;
      this.emitAuthState();
    }
  }
  login(
   clickStream$: BehaviorSubject<any>
  ) {

     this.response$ = clickStream$.switchMap(click =>  {
                      return this.webServiceUtil.testLogin();
                                                      }
                                            );
     this.response$.subscribe((response:Response) => {
          this.setAuthState(AuthState.LOGGED_IN);
      },
     (err:any)          => {
         this.setAuthState(AuthState.LOGGED_OUT);  
     })
  }

  logout() {
      if (this.authState === AuthState.LOGGED_IN) {
         this.setAuthState(AuthState.LOGGED_OUT);
      }
  }
}

在页面更改或执行HTTP请求时,可能会触发RESET_COUNTDOWN事件.这将迫使倒数再次开始,同时只有一个订阅,因此要跟踪一系列订阅.要在重置后立即取消.

A RESET_COUNTDOWN event can get fired on things like a change of page or when doing HTTP requests. That will force the countdown to begin again, whilst only ever having one subscription, hence the keeping track of an array of subscriptions.. That you immediately cancel on reset.

这篇关于实施Ionic/Angular的会话超时服务,并在每次新用户交互时重置计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆