Ionic 6 AppState 更改导致重复的订阅结果

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

我正在使用 Ionic 6 和 SignalR 制作一个聊天应用程序,仅用于测试目的。我有一个聊天详细信息页面,在该页面中我正在监听从 SignalR 触发的BehaviorSubject。这是我的工作原理:

  1. 发件人发送消息
  2. 发送方在 SignalR 中触发“CheckMessage”
  3. Receiver 的 SignalR 获取它并触发我在聊天详细信息页面订阅的BehaviorSubject。
  4. 它获取最后发送的消息并将其显示在屏幕上。

一切都按预期进行,但是当我最小化应用程序并重新打开它时,在发送/接收新消息后,它在屏幕上显示两次。当我重复此操作时,最后一条消息会在屏幕上显示 n 次(n = 我最小化应用程序的次数)。

我该如何解决这个问题或者我在这里缺少什么?

signalR.cs:

public async Task CheckMessage(int chatId)
{
    try
    {
        await Clients.OthersInGroup("group-" + chatId.ToString()).SendAsync("NewMessage", chatId);
    }
    catch (Exception ex)
    {
        await _log.InsertErrorLog(ex);
    }
}

app.component.ts:

constructor(....) {
    App.addListener("appStateChange", result => {
        if (result.isActive) {
            this.signalR.createHubConnection();
        } else {
            this.signalR.stopHubConnection();
        }
    });
}

ngOnDestroy(): void {
    App.removeAllListeners();
}

signalR.service.ts:

createHubConnection() {
    this.hubConnection = new HubConnectionBuilder()
        .withUrl(this.hubUrl + 'URL?SOME_PARAMETERS', {
            accessTokenFactory: () => USER_TOKEN
        })
        .withAutomaticReconnect()
        .build();

    this.hubConnection.start();

    this.hubConnection.on('NewMessage', id => {
        this.zone.run(() => { 
            this.v.newChatMessage$.next(id);
        });
    });
}

stopHubConnection() {
    if (this.hubConnection) {
        this.hubConnection.stop();
    }
}

async checkNewMessages(id: number) { 
    return this.hubConnection.invoke('CheckMessage', id);
}

v.component.ts:

newChatMessage$: Subject<number> = new BehaviorSubject(0);

detail.component.ts:

sub: Subscription;

ngOnInit() { 
    if (this.sub == undefined) {
        this.sub = this.v.newChatMessage$.subscribe(id => { 
            if (id > 0 && id == this.chat.id) {
                this.service.getLastMessage(id).pipe(take(1)).subscribe(msg => {
                    this.messages.push(msg);
                    this.scrollToBottom();
                });
                
                this.v.newChatMessage$.next(0);
            }
        })
    }
}

sendMessage() {
    this.service.addMessage(MESSAGE_ITEM).pipe(take(1)).subscribe(result => {
        this.messages.push(result);
        this.signalR.checkNewMessages(this.chat.id);
        this.scrollToBottom();
    });
}

ngOnDestroy(): void {
    if (this.sub) { this.sub.unsubscribe(); }
}
angular ionic-framework
1个回答
0
投票

发生这种情况是因为在detail.component 的 ngOnInit() 生命周期中,每次启动时您都会收到最后一条消息:

this.service.getLastMessage(id).pipe(take(1)).subscribe(msg => {
 this.messages.push(msg);
});

解决方案:在执行

this.messages.push(msg)
之前(或者最好在您的
service.getLastMessage()
函数中)以某种方式检查最后一条消息是否已经存在,如果不存在,则添加它;像这样的东西:

if (!this.messages.includes(msg)) { //better check whith an id, rather than the text
  this.messages.push(msg);
}
© www.soinside.com 2019 - 2024. All rights reserved.