جاوااسکریپت - @ng-idle/core: تمام شدن زمان انتظار در یک نمونه بیکار باعث میشود توقف در نمونه بیکار دیگر کار نکند
من از "@ng-idle/core": "~11.1.0" و برنامه Angular 13 استفاده میکنم.
من دو نمونه غیرفعال دارم، یکی برای خروج خودکار و دیگری برای محافظ صفحه نمایش.
اگر اسکرینسیور من «فعال» باشد و اگر تایماوت در اولین حالت رخ دهد (یعنی خروج خودکار) و اگر سعی کنم صفحه را قطع کنم، اسکرینسیور خاموش نمیشود و رابط کاربری را مسدود میکند. (یک چیز واضح است که اشتراک توقف وقفه در این سناریو کار نمیکند).
چطور این مسئله را حل کنیم؟
نمونه کد برای مرجع:
import {Component, NgZone, OnInit} from '@angular/core';
import {DEFAULT_INTERRUPTSOURCES, Idle, LocalStorage, LocalStorageExpiry} from '@ng-idle/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
title = 'my-idle-app';
private readonly screenSaver!: HTMLElement;
private readonly screenSaverText!: Text;
idleTime1: number = 1;
private screenSaverIdle = new Idle(new LocalStorageExpiry(new LocalStorage()), this.ngZone);
constructor(readonly ngZone: NgZone, private idle1: Idle) {
this.screenSaver = document.createElement('div');
this.screenSaver.id = 'screensaver';
this.screenSaver.className = 'screen-saver';
this.screenSaverText = document.createTextNode('---%');
const movingTxt = document.createElement('span');
movingTxt.appendChild(this.screenSaverText);
this.screenSaver.appendChild(movingTxt);
this.removeScreenSaver();
this.screenSaverIdle.setIdleName('screenSaverIdleService');
this.screenSaverIdle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
this.screenSaverIdle.setTimeout(false);
this.screenSaverIdle.setIdle(10);
this.screenSaverIdle.watch();
this.screenSaverIdle.onIdleStart.subscribe(() => {
document.body.appendChild(this.screenSaver);
});
this.screenSaverIdle.onIdleEnd.subscribe(() => {
console.log('IDLE END ::');
this.removeScreenSaver();
});
}
ngOnInit() {
this.idle1.setIdleName('AutoLogoutIdleService');
this.idle1.setInterrupts(DEFAULT_INTERRUPTSOURCES);
this.idle1.setIdle(this.idleTime1);
this.idle1.setTimeout(10);
this.idle1.onIdleStart.subscribe(() => {
console.log("IDLE 1 STARTS")
});
this.idle1.onIdleEnd.subscribe({
next: () => {
console.log("IDLE 1 END");
},
complete: () => {
console.log("idle 1 completed");
}
});
this.idle1.onTimeout.subscribe(()=> {
console.log("User session timed Out",);
});
this.idle1.watch();
}
private removeScreenSaver() {
const ex = document.getElementById('screensaver');
if (ex) {
document.body.removeChild(ex);
}
}
}
من کد منبع کتابخانه ng-idle را تجزیه و تحلیل کردم و به نظر میرسد که از آنجایی که مقدار timeout برای نمونهی idle محافظ صفحه نمایش "false" است، نباید اشتراک وقفه را لغو کند.
پس، سوال من مربوط به نمونههای ایجاد شده از سرویسها خواهد بود. آیا اینجا باعث ایجاد مشکل میشود؟
پاسخ شماره ۱
نگاه کردن به کد منبع باعث میشود متوقف کردن/ریست کردن تایمر ng-idle2 دشوار باشد. بنابراین من فقط تایمر اسکرینسیور را متوقف و دوباره شروع میکنم و به نظر میرسد این به خوبی کار میکند.
this.idle1.onTimeout.subscribe(() => {
console.log('User session timed Out');
this.removeScreenSaver();
this.screenSaverIdle.stop();
this.screenSaverIdle.watch();
});
کد کامل:
import { Component, NgZone, OnInit } from '@angular/core';
import {
DEFAULT_INTERRUPTSOURCES,
Idle,
LocalStorage,
LocalStorageExpiry,
} from '@ng-idle/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
title = 'my-idle-app';
private readonly screenSaver!: HTMLElement;
private readonly screenSaverText!: Text;
idleTime1: number = 1;
private screenSaverIdle = new Idle(
new LocalStorageExpiry(new LocalStorage()),
this.ngZone
);
constructor(readonly ngZone: NgZone, private idle1: Idle) {
this.screenSaver = document.createElement('div');
this.screenSaver.id = 'screensaver';
this.screenSaver.className = 'screen-saver';
this.screenSaverText = document.createTextNode('---%');
const movingTxt = document.createElement('span');
movingTxt.appendChild(this.screenSaverText);
this.screenSaver.appendChild(movingTxt);
this.removeScreenSaver();
this.screenSaverIdle.setIdleName('screenSaverIdleService');
this.screenSaverIdle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
this.screenSaverIdle.setTimeout(false);
this.screenSaverIdle.setIdle(10);
this.screenSaverIdle.watch();
this.screenSaverIdle.onIdleStart.subscribe(() => {
console.log(
`Screen saver Active:: ${this.screenSaverIdle.getIdle()}::${this.screenSaverIdle.getTimeout()}::${this.screenSaverIdle.isIdling()}::${this.screenSaverIdle.isRunning()}`
);
document.body.appendChild(this.screenSaver);
});
this.screenSaverIdle.onIdleEnd.subscribe(() => {
console.log('Screen saver Idle end ::');
this.removeScreenSaver();
});
}
ngOnInit() {
this.idle1.setIdleName('AutoLogoutIdleService');
this.idle1.setInterrupts(DEFAULT_INTERRUPTSOURCES);
this.idle1.setIdle(this.idleTime1);
this.idle1.setTimeout(30);
this.idle1.onIdleStart.subscribe(() => {
console.log('IDLE 1 STARTS');
});
this.idle1.onIdleEnd.subscribe({
next: () => {
console.log('IDLE 1 END');
},
complete: () => {
console.log('idle 1 completed');
},
});
this.idle1.onTimeout.subscribe(() => {
console.log('User session timed Out');
this.removeScreenSaver();
this.screenSaverIdle.stop();
this.screenSaverIdle.watch();
});
this.idle1.watch();
}
private removeScreenSaver() {
const ex = document.getElementById('screensaver');
console.log(ex);
if (ex) {
document.body.removeChild(ex);
}
}
}
