TDLib 中“UpdateNewChat”事件中的意外聊天

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

我在 TDLib 中使用

UpdateNewChat
方法时遇到
LoadChats
事件问题。有时,我会收到我不再是或从未成为成员的聊天的更新。这包括存档的聊天记录、已删除的聊天记录以及我之前留下的公开聊天记录。我还遇到了实际上是连接到频道的群组的聊天(但是,在这些频道中,我是成员)。

重现步骤:

  1. 调用
    LoadChats
    方法。
  2. 观察
    UpdateNewChat
    UpdateChatPosition
    事件。

预期行为:仅接收我当前所属的聊天的更新。

实际行为:接收我不是其成员或过去已离开的聊天的更新。

环境:

tdlib.native版本:1.8.29(来自nuget)

tdlib 版本:1.8.29(来自 nuget)

编程语言:C# 11

(.NET8)

问题:

UpdateNewChat
事件到底发送什么,它是如何工作的?文档提到应该在加载或创建聊天时处理此事件,但它没有解释这些聊天来自哪里。我预计只会收到我当前所属的聊天记录(即使它们已存档)。这种行为是否符合预期,或者我处理此事件的方式可能存在问题?为什么此活动会带来我不再是其成员的聊天?

我的更新处理程序:

internal static class CommonUpdateHandlerMethods
{
    public static async void UpdateChatListHanlder(object sender, TdApi.Update e)
    {
        var client = (TdClient)sender;
        switch (e)
        {
            case TdApi.Update.UpdateNewChat newChat:
                {
                    await UpdateNewChat(client, newChat.Chat.Id);
                    break;
                }
            case TdApi.Update.UpdateChatPosition chatPos:
                {
                    if (chatPos.Position.Order == CommonConstants.TdApi.ShouldRemoveChat)//ShouldRemoveChat = 0
                    {
                        switch (chatPos.Position.List)
                        {
                            case TdApi.ChatList.ChatListArchive:
                                {
                                    CommonData.ArchiveChatList.Remove(chatPos.ChatId, out _);
                                    break;
                                }
                            case TdApi.ChatList.ChatListMain:
                                {
                                    CommonData.MainChatList.Remove(chatPos.ChatId, out _);
                                    break;
                                }
                        }
                    }
                    else
                    {
                        await UpdateNewChat(client, chatPos.ChatId);
                    }
                    break;
                }
        }
    }

    private static async Task UpdateNewChat(TdClient client, long newChatId)
    {
        var chat = await client.GetChatAsync(newChatId);
        if (chat.ChatLists.Any(list => list is TdApi.ChatList.ChatListArchive))
        {
            CommonData.ArchiveChatList.AddOrUpdate(chat.Id, chat, (id, chat) => chat);
        }
        else if (chat.ChatLists.Any(list => list is TdApi.ChatList.ChatListMain))
        {
            CommonData.MainChatList.AddOrUpdate(chat.Id, chat, (id, chat) => chat);
        }
        else
        {
            CommonData.UnkownChatList.AddOrUpdate(chat.Id, chat, (id, chat) => chat);
        }
    }
}

CommonData 类:

 internal static class CommonData
 {
   public static ConcurrentDictionary<long, TdApi.Chat> MainChatList { get; set; } = [];
   public static ConcurrentDictionary<long, TdApi.Chat> ArchiveChatList { get; set; } = [];
   public static ConcurrentDictionary<long, TdApi.Chat> UnkownChatList { get; set; } = [];
 }

助手类:

internal static class Helper
{
    private static async Task InnerLoadChatsAsync(TdClient client, TdApi.ChatList chatList, int delay)
    {
        try
        {
            while (true)
            {
                await client.LoadChatsAsync(chatList, CommonConstants.DefaultLimit);
                Thread.Sleep(delay);
            }
        }
        catch (Exception ex)
        {
            if (ex is TdException tde && tde.Error.Code == CommonConstants.ErrorCodes.NotFound)//NotFound = 404
                return;
            else
                throw;
        }
    }
    internal static async Task LoadChatsAsync(TdClient client, int delay = CommonConstants.DefaultLoadChatDelay)//DefaultLoadChatDelay = 100
    {
        await InnerLoadChatsAsync(client, new TdApi.ChatList.ChatListArchive(), delay);
        await InnerLoadChatsAsync(client, new TdApi.ChatList.ChatListMain(), delay);
    }
}

我的测试方法:

public static async Task TestLoadChats(TdClient client)
{
    await Helper.LoadChatsAsync(client);
    Console.WriteLine("CHATM[{0}]", CommonData.MainChatList.Count);
    Console.WriteLine("CHATA[{0}]", CommonData.ArchiveChatList.Count);
    using var sw = new StreamWriter("finfo.txt");
    foreach (var chat in CommonData.UnkownChatList)
    {
        sw.WriteLine("{0}\n {1}\n {2}\n--------------------------------------", chat.Key, chat.Value.Title, chat.Value.Type.DataType);
    }
    Console.WriteLine("CHATU[{0}]", CommonData.UnkownChatList.Count);
}
c# telegram chat tdlib
1个回答
0
投票

每次

发现
新聊天时都会发送updateNewChat消息。这还包括您的联系人发送的消息引用的聊天。

TDLib 入门页面 说:

[应用程序]必须维护通过此更新收到的聊天的缓存。

创建所有已发现聊天的缓存后,您可以通过检测

updateChatAddedToList
消息来过滤您当前所属的聊天。具体来说,您对属于
chatListMain
的聊天感兴趣。

这是此类消息的示例:

{
  "@type": "updateChatAddedToList",
  "chat_id": 1111111,
  "chat_list": {
    "@type": "chatListMain"
  },
  "@client_id": 1
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.