signalR .net core 3.1 和 ionic 5 + angular 8 在停止和启动集线器时重复消息

signalR .net core 3.1 and ionic 5 + angular 8 duplicates messages when stop and start hub

我在 .net core 3.1 项目中使用 SignalR 作为服务器,使用 ionic 5 + angular 8 作为客户端,我对 bub 连接有奇怪的行为,对于每个 stop/start 集线器消息被进一步复制。 第一次一条消息,第二次2条重复消息,第三次3条重复消息等

@aspnet/singalr版本为1.1.4

服务器代码是:

services.AddSignalR();
app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapHub<MyHub>("/myHub");
            });

HubManager

public class MyHubManager<T> : IMyHubManager<T> where T : class
{
    private IHubContext<MyHub> context;

    public MyHubManager(IHubContext<MyHub> context)
    {
        this.context = context;
    }

    public async Task SendGroupMessageAsync(string groupId, T message)
    {
        await context.Clients.Group(groupId).SendAsync(groupId , message);
    }
}

客户端:

import { Injectable } from '@angular/core';
import * as signalR from '@aspnet/signalr';
import { Subject } from 'rxjs';
import { NewMessage } from '../new.message';

@Injectable({
    providedIn: 'root'
})
export class SignalRService {

    private hubConnection: signalR.HubConnection
    public message$: Subject<NewMessage> = new Subject<NewMessage>();

    constructor() {
    }

    public init(id: string, hub: string, token: string) {
        if (!this.hubConnection) {
            console.log('init signalR');
            this.hubConnection = new signalR.HubConnectionBuilder()
                .withUrl(`http://ipaddress/${hub}?groupId=group${id}`, {
                    accessTokenFactory: () => token
                })
                .build();
            this.hubConnection.start().then(() => {
                console.log('hub connection started');
            }).catch(err => {
                console.log(err);
            });

            this.hubConnection.on(`group${id}`, (message: NewMessage) => {
                console.log('signalR pass message');
                this.message$.next(message);
            });
        }
    }

    public closeConnection() {
        if (this.hubConnection) {
            console.log('close connection');
            this.hubConnection.stop();
            this.hubConnection = null;
        }
    }
}

订阅在另一个使用 singalR 服务的页面

export class MyPage {

  constructor(private signalRService: SignalRService) { }

  ionViewDidEnter() {
          this.initSignalRConnection();
  }

  initSignalRConnection(){
    this.signalRService.init('1234', 'myHub', 'token');
    this.signalRService.message$.subscribe((message: NewMessage) => {
      console.log('got message');
      this.handleMessage(message);
    });
  }

  ionViewWillLeave(){
    this.signalRService.closeConnection();
  }
}

消息不会重复,您只需多次处理它们。发生这种情况是因为您总是在连接时调用 this.signalRService.message$.subscribe 而从不在断开连接时执行取消订阅。