You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何传入SignalR accessTokenFactory的Observable仅会执行一次

问题根源

  • 调用connect方法时你已经执行了getAccessToken(),传入的是单次请求生成的Observable对象,该对象仅会在首次订阅时触发MSAL取令牌逻辑,后续复用不会产生新的令牌请求。
  • connect方法内提前创建了固定的token$流,accessTokenFactory每次执行都复用该流转Promise的结果,RxJS 中单播Observable转Promise后只会返回首次订阅的缓存值,不会重新执行上游取令牌逻辑。

解决方案

调整逻辑为每次SignalR需要令牌时,都重新触发getAccessToken()调用:

步骤1:调整connect方法的入参类型和内部实现

将入参从已生成的Observable改为返回Observable的工厂函数,每次令牌工厂被调用时才生成新的取令牌流:

import { firstValueFrom } from 'rxjs'; // RxJS 7+ 需引入,低版本可省略使用toPromise

connect(accessTokenProvider: () => Observable<any>): Promise<any> {
    const options: IHttpConnectionOptions = {
      accessTokenFactory: async () => {
        // 每次调用都重新执行取令牌逻辑,自动处理令牌刷新
        const authResult = await firstValueFrom(accessTokenProvider());
        return authResult.accessToken;
        // RxJS 6及以下版本可使用原有toPromise写法:
        // return accessTokenProvider().pipe(map(res => res.accessToken)).toPromise();
      }
    };

    this.connection = new HubConnectionBuilder()
      .withUrl(this.hubUrl, options)
      // 其余原有逻辑保持不变
 }

步骤2:调整connect方法的调用方式

不要直接执行getAccessToken传入结果,改为传入箭头函数包裹调用逻辑:

this._realTimeNotificationService.connect(() => this._authService.getAccessToken(environment.backendUrl));

修改完成后,SignalR首次建连、自动重连时都会重新执行令牌工厂逻辑,MSAL的acquireTokenSilent会自动判断当前令牌有效性,过期时自动用刷新令牌换取新的有效令牌,即可解决重连时使用过期令牌的问题。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:15:01