为 Ionic/Angular 实现 Session Timeout 服务,每次新的用户交互都会重置 Timer
Posted
技术标签:
【中文标题】为 Ionic/Angular 实现 Session Timeout 服务,每次新的用户交互都会重置 Timer【英文标题】:Implementing Session Timeout service for Ionic/Angular, with Timer Reset with each new user interaction 【发布时间】:2018-01-30 15:31:03 【问题描述】:我正在尝试调整我为会话超时创建的一些代码。 每当用户与该功能交互时,我想重置计时器以再次开始倒计时。我很难弄清楚如何将类似的代码注入到这个example
C# 代码 - 我正在尝试集成:
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.");
);
据我所知,Typescript RxJS 相当于 RxJS 库的 C# 风格,我的变量名映射是:
C#/example Typescript/mine
update resetManager
.Select .map
(来自here-(见标签标题)).OnNext .next
.Interval .timer
我在想我可以插入一个 do 并链接 resetManager - 但由于一个是布尔值而另一个是 AuthState 我似乎遇到了困难。
我想知道 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;
【问题讨论】:
【参考方案1】:我终于想出了如何做到这一点......
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);
RESET_COUNTDOWN 事件可能会在页面更改或执行 HTTP 请求时触发。这将迫使倒计时重新开始,而只有一个订阅,因此会跟踪一系列订阅。您会在重置时立即取消。
【讨论】:
以上是关于为 Ionic/Angular 实现 Session Timeout 服务,每次新的用户交互都会重置 Timer的主要内容,如果未能解决你的问题,请参考以下文章
Cordova笔记三:ionic+angular+cordova技术栈
如何将 Ionic3 angular4 混合应用程序构建为 ios .ipa 文件?
Ionic & Angular - iOS 上的 Ion 日期时间设计
在 ionic 4 + Angular 中将日期转换为 DD/MM/YYYY
如何在 javascript (ionic | Angular | NodeJS | MongoDB) 中将包含对象的数组展平和减少为逗号分隔的字符串