我在 TDLib 中使用
UpdateNewChat
方法时遇到 LoadChats
事件问题。有时,我会收到我不再是或从未成为成员的聊天的更新。这包括存档的聊天记录、已删除的聊天记录以及我之前留下的公开聊天记录。我还遇到了实际上是连接到频道的群组的聊天(但是,在这些频道中,我是成员)。
LoadChats
方法。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);
}
每次
发现新聊天时都会发送
updateNewChat
消息。这还包括您的联系人发送的消息引用的聊天。
TDLib 入门页面 说:
[应用程序]必须维护通过此更新收到的聊天的缓存。
创建所有已发现聊天的缓存后,您可以通过检测
updateChatAddedToList
消息来过滤您当前所属的聊天。具体来说,您对属于 chatListMain
的聊天感兴趣。
这是此类消息的示例:
{
"@type": "updateChatAddedToList",
"chat_id": 1111111,
"chat_list": {
"@type": "chatListMain"
},
"@client_id": 1
}