SignalR .net core 3.1 и ionic 5 angular 8 дублируют сообщения при остановке и запуске концентратора

#angular #asp.net-core #ionic-framework #signalr

#angular #asp.net-core #ionic-framework #signalr

Вопрос:

Я использую SignalR в проекте .net core 3.1 в качестве сервера, а ionic 5 angular 8 в качестве клиента, у меня странное поведение с подключением bub, для каждого концентратора остановки / запуска сообщение дополнительно дублируется. В первый раз одно сообщение, во второй раз 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();
  }
}
  

Комментарии:

1. Можете ли вы опубликовать, какие изменения вы внесли, чтобы это работало? Я застрял в этой же проблеме, и мое представление html не обновляется при перезагрузке обновления SignalR. Я использую асинхронный оператор в своем HTML-шаблоне.

Ответ №1:

Сообщения не дублируются, вы просто обрабатываете их несколько раз. Это происходит потому, что вы всегда вызываете this.signalRService.message$.subscribe connect и никогда не выполняете unsbsribe при отключении.

Комментарии:

1. Да, это была проблема, я наконец понял 🙂 спасибо!