用户登录角度后如何检查所有选项卡中的一个空闲超时

问题描述 投票:0回答:2

我需要在用户登录后检查不活动的用户。用户可以在不同的选项卡中使用该应用程序。我为这项任务实现了一些解决方案,但每个解决方案都有一些问题。

  1. 使用idle-ng库:它仅适用于一个选项卡(我在登录组件中调用它),如果我在应用程序组件中调用它,它只运行一次,注销后,它不会在登录组件中运行。
  2. 使用@hostlistener('click'):例如,当我在应用程序组件中调用它时,它仅在一个选项卡中运行,不会检查其他选项卡。

你能帮我吗?

angular authentication timeout
2个回答
0
投票

本地存储?

它是按域绑定而不是按选项卡绑定,因此您可以将上次活动时间戳存储在其中。

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 个选项卡每分钟左右都访问它。


0
投票

它对我有用

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.');
    });

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.