我想在用户闲置20分钟时提醒他。所以,创建了一个服务。
它在桌面上工作得很好,但在手机上却没有显示出来,有时如果屏幕在后台停留了几个小时,那么一旦我再次进入页面,注销对话框屏幕就会开始倒计时。
我的意思是它应该注销,我应该看到登录页面,但在这里,它显示注销警报倒计时页面后几个小时,否则它不显示在手机浏览器。
这是我的代码,请告诉我我遗漏了哪些逻辑。
这里是Service.ts文件,check()会每5秒被调用一次,20秒后会显示注销提醒......
const MINUTES_UNITL_AUTO_LOGOUT = 0.2; // 1 mins- 20
const CHECK_INTERVAL = 5000; // checks every 5 secs- 5000
@Injectable({
providedIn: "root",
})
export class AutoLogoutService {
logOutInterval: any;
constructor(
private localStorage: LocalStoreManager,
private authService: AuthService,
public dialog: MatDialog
) {
this.localStorage.savePermanentData(
Date.now().toString().toString(),
DBkeys.AUTO_LOGOUT
);
this.initListener();
}
initListener() {
document.body.addEventListener("click", () => this.reset());
document.body.addEventListener("mouseover", () => this.reset());
document.body.addEventListener("mouseout", () => this.reset());
document.body.addEventListener("keydown", () => this.reset());
document.body.addEventListener("keyup", () => this.reset());
document.body.addEventListener("keypress", () => this.reset());
}
reset() {
this.setLastAction(Date.now());
}
initInterval() {
this.logOutInterval = setInterval(() => {
this.check();
}, CHECK_INTERVAL);
}
clearInterval() {
clearInterval(this.logOutInterval);
}
check() {
const now = Date.now();
const timeleft = this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
const diff = timeleft - now;
const isTimeout = diff < 0;
console.log(diff);
if (isTimeout && !this.authService.isLogoutDialogOpenned) {
this.authService.isLogoutDialogOpenned = true;
this.dialog
.open(LogoutDialog, {
maxWidth: "100vw",
})
.afterClosed()
.subscribe((result) => {
this.authService.isLogoutDialogOpenned = false;
});
}
}
public getLastAction() {
return parseInt(this.localStorage.getData(DBkeys.AUTO_LOGOUT));
}
public setLastAction(lastAction: number) {
this.localStorage.savePermanentData(
lastAction.toString(),
DBkeys.AUTO_LOGOUT
);
}
}
我相信在手机上,当用户最小化浏览器时,你的逻辑就会停止执行,因为手机会为了内存管理而自动杀死后台应用程序,当他重新启动浏览器时,你的脚本就会重新启动。你也应该在destroy或window.beforeunload事件时注销。
谢谢你的建议,但下面的解决方案对我来说是有效的。
使用了ngZone,它在后台运行。
initInterval() {
this.ngZone.runOutsideAngular(() => {
this.logOutInterval = setInterval(() => {
this.check();
}, CHECK_INTERVAL);
})
}
clearInterval() {
clearInterval(this.logOutInterval);
}
check() {
const now = Date.now();
const timeleft =
this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
const diff = timeleft - now;
const isTimeout = diff < 0;
const isBackgroundLogoutEnabled = diff < -ONE_MINUTE;
this.ngZone.run(() => {
if (isTimeout && !this.authService.isLogoutDialogOpenned) {
this.authService.isLogoutDialogOpenned = true;
this.dialog
.open(LogoutDialog, {
maxWidth: "100vw",
})
.afterClosed()
.subscribe((result) => {
this.authService.isLogoutDialogOpenned = false;
});
}
if(isBackgroundLogoutEnabled){
this.clearInterval();
this.authService.isLogoutDialogOpenned = false;
this.authService.logout();
this.authService.redirectLogoutUser();
this.dialog.closeAll();
}
});
}