我需要在用户登录后检查不活动的用户。用户可以在不同的选项卡中使用该应用程序。我为这项任务实现了一些解决方案,但每个解决方案都有一些问题。
你能帮我吗?
本地存储?
它是按域绑定而不是按选项卡绑定,因此您可以将上次活动时间戳存储在其中。
app.component
(大概):
private readonly userActivityKey: string = 'user-activity';
@HostListener...
public ngOnInit(): void {
setInterval(() => this.checkUserActivity(), 60000); // that's a minute, right?
}
public onClickEvent(): void {
localStorage.setItem(this.userActivityKey, new Date());
}
private checkUserActivity(): void {
const lastActiveDateTime = localStorage.getItem(this.userActivityKey);
// check the time...
}
每次单击时,每个选项卡都会更新本地存储值,并且所有选项卡都会从计时器上的同一位置读取。
访问本地存储的成本并不高,不可能让 50 个选项卡每分钟左右都访问它。
它对我有用
import { Injectable } from '@angular/core';
import { Observable, Subject, fromEvent, merge, timer } from 'rxjs';
import { mapTo } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class IdleServiceService {
private activityEvents$: Observable<any>;
private activityDetected$: Subject<void> = new Subject<void>();
private idleThreshold: number = 5000; // 5 minutes in milliseconds
private idleTimer: any;
constructor() {
// Define user activity events to observe
const mousemove$ = fromEvent(document, 'mousemove');
const keydown$ = fromEvent(document, 'keydown');
// Merge different user activity events
this.activityEvents$ = merge(mousemove$, keydown$).pipe(
mapTo(true)
);
// Subscribe to activity events and reset idle timer
this.activityEvents$.subscribe(() => this.resetIdleTimer());
}
// Method to reset idle timer
private resetIdleTimer(): void {
clearTimeout(this.idleTimer);
this.idleTimer = setTimeout(() => {
this.activityDetected$.next();
}, this.idleThreshold);
}
// Method to get idle time observable
getIdleTime(): Observable<void> {
return this.activityDetected$.asObservable();
}
}
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { IconSetService } from '@coreui/icons-angular';
import { iconSubset } from './icons/icon-subset';
import { Title } from '@angular/platform-browser';
import { IdleServiceService } from './views/pages/idle-service.service';
@Component({
selector: 'app-root',
template: '<router-outlet></router-outlet>',
})
export class AppComponent implements OnInit {
title = 'Time Tracking Tool';
constructor(
private router: Router,
private titleService: Title,
private iconSetService: IconSetService,
private idleService: IdleServiceService
) {
titleService.setTitle(this.title);
// iconSet singleton
iconSetService.icons = { ...iconSubset };
}
ngOnInit(): void {
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) {
return;
}
});
this.idleService.getIdleTime().subscribe(() => {
console.log('User is idle.');
});
}
}