firemail

标题: 初始聊天列表数据加载逻辑ChatList [打印本页]

作者: Qter    时间: 2020-3-20 11:50
标题: 初始聊天列表数据加载逻辑ChatList
本帖最后由 Qter 于 2020-3-25 19:19 编辑

  1. >        LongChat.exe!Dialogs::IndexedList::addToEnd(Dialogs::Key key) 行 24        C++
  2.          LongChat.exe!Dialogs::Entry::addToChatList(Dialogs::Mode list, gsl::not_null<Dialogs::IndexedList *> indexed) 行 156        C++        
  3.          LongChat.exe!DialogsInner::createDialog(Dialogs::Key key) 行 1258        C++
  4.          LongChat.exe!DialogsWidget::createDialog(Dialogs::Key key) 行 369        C++
  5.          LongChat.exe!MainWidget::createDialog(Dialogs::Key key) 行 1562        C++
  6.          LongChat.exe!Dialogs::Entry::setChatListExistence(bool exists) 行 97        C++
  7.          LongChat.exe!Dialogs::Entry::updateChatListSortPosition() 行 87        C++
  8. >        LongChat.exe!Dialogs::Entry::setChatListTimeId(int date) 行 146        C++
  9.          LongChat.exe!History::setChatListMessage(HistoryItem * item) 行 2201        C++
  10.          LongChat.exe!History::setChatListMessageFromLast() 行 2267        C++
  11.          LongChat.exe!History::requestChatListMessage() 行 2282        C++
  12.          LongChat.exe!History::setLastMessage(HistoryItem * item) 行 2179        C++
  13.          LongChat.exe!History::addNewItem(gsl::not_null<HistoryItem *> item, bool unread) 行 999        C++
  14.          LongChat.exe!History::addNewToLastBlock(const MTPBoxed<MTPmessage> & msg, NewMessageType type) 行 657        C++
  15.          LongChat.exe!History::addNewMessage(const MTPBoxed<MTPmessage> & msg, NewMessageType type) 行 640        C++
  16.          LongChat.exe!Data::Session::addNewMessage(const MTPBoxed<MTPmessage> & data, NewMessageType type) 行 1465        C++
  17.          LongChat.exe!App::feedMsgs(const QVector<MTPBoxed<MTPmessage>> & msgs, NewMessageType type) 行 225        C++
  18.          LongChat.exe!DialogsWidget::applyReceivedDialogs(const QVector<MTPBoxed<MTPdialog>> & dialogs, const QVector<MTPBoxed<MTPmessage>> & messages) 行 668        C++
  19.          LongChat.exe!DialogsWidget::dialogsReceived(const MTPBoxed<MTPmessages_dialogs> & dialogs, int requestId) 行 550        C++
  20.          LongChat.exe!RPCDoneHandlerOwnedReq<void,DialogsWidget,MTPBoxed<MTPmessages_dialogs>>::operator()(int requestId, const int * from, const int * end) 行 406        C++
  21.          LongChat.exe!MTP::Instance::Private::execCallback(int requestId, const int * from, const int * end) 行 1068        C++
  22.          LongChat.exe!MTP::Instance::execCallback(int requestId, const int * from, const int * end) 行 1710        C++
  23.          LongChat.exe!MTP::internal::Session::tryToReceive() 行 630        C++
复制代码
返回的结果集,其中的Vector<Dialog>为左侧聊天人员列表
messages.dialogsSlice#<font color="#ff0000">71e094f3 </font>count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
其中的Dialog相关字段如下:
  1. dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
复制代码
其对应的发送请求为
messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;

根据发磅请求的id b098aee6 找到对应处理函数
result.insert(mtpc_messages_getDialogs, Serialize_messages_getDialogs);
  1. void Serialize_messages_getDialogs(MTPStringLogger &to, int32 stage, int32 lev, Types &types, Types &vtypes, StagesFlags &stages, StagesFlags &flags, const mtpPrime *start, const mtpPrime *end, uint32 iflag) {
  2.         auto flag = MTPmessages_getDialogs::Flags::from_raw(iflag);

  3.         if (stage) {
  4.                 to.add(",\n").addSpaces(lev);
  5.         } else {
  6.                 to.add("{ messages_getDialogs");
  7.                 to.add("\n").addSpaces(lev);
  8.         }
  9.         switch (stage) {
  10.         case 0: to.add("  flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_flags); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  11.         case 1: to.add("  exclude_pinned: "); ++stages.back(); if (flag & MTPmessages_getDialogs::Flag::f_exclude_pinned) { to.add("YES [ BY BIT 0 IN FIELD flags ]"); } else { to.add("[ SKIPPED BY BIT 0 IN FIELD flags ]"); } break;
  12.         case 2: to.add("  offset_date: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  13.         case 3: to.add("  offset_id: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  14.         case 4: to.add("  offset_peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  15.         case 5: to.add("  limit: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  16.         case 6: to.add("  hash: "); ++stages.back(); types.push_back(mtpc_int+0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
  17.         default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
  18.         }
  19. }
复制代码
里面加断点,找到对应的发送时机
  1.          LongChat.exe!Serialize_messages_getDialogs(MTPStringLogger & to, int stage, int lev, QVector<unsigned int> & types, QVector<unsigned int> & vtypes, QVector<int> & stages, QVector<int> & flags, const int * start, const int * end, unsigned int iflag) 行 43179        C++
  2.          LongChat.exe!mtpTextSerializeType(MTPStringLogger & to, const int * & from, const int * end, int cons, unsigned int level, int vcons) 行 45824        C++
  3.          LongChat.exe!mtpTextSerializeCore(MTPStringLogger & to, const int * & from, const int * end, unsigned int cons, unsigned int level, int vcons) 行 288        C++
  4.          LongChat.exe!mtpTextSerializeType(MTPStringLogger & to, const int * & from, const int * end, int cons, unsigned int level, int vcons) 行 45826        C++
  5.          LongChat.exe!mtpTextSerialize(const int * & from, const int * end) 行 854        C++
  6.          LongChat.exe!MTP::internal::ConnectionPrivate::sendSecureRequest(MTP::SecureRequest && request, bool needAnyResponse, QReadLocker & lockFinished) 行 3136        C++
  7.          LongChat.exe!MTP::internal::ConnectionPrivate::tryToSend() 行 1042        C++
复制代码
这种方法跟踪不到具体代码中的发送位置

回到scheme.h中找到对些发送结构的定义
  1. class MTPmessages_getDialogs { // RPC method 'messages.getDialogs'
  2. public:
  3.         enum class Flag : uint32 {
  4.                 f_exclude_pinned = (1U << 0),
  5.                 MAX_FIELD = (1U << 0),
  6.         };
  7.         using Flags = base::flags<Flag>;
  8.         friend inline constexpr auto is_flag_type(Flag) { return true; };

  9.         bool is_exclude_pinned() const { return vflags.v & Flag::f_exclude_pinned; }

  10.         MTPflags<MTPmessages_getDialogs::Flags> vflags;
  11.         MTPint voffset_date;
  12.         MTPint voffset_id;
  13.         MTPInputPeer voffset_peer;
  14.         MTPint vlimit;
  15.         MTPint vhash;

  16.         MTPmessages_getDialogs() = default;
  17.         MTPmessages_getDialogs(const MTPflags<MTPmessages_getDialogs::Flags> &_flags, MTPint _offset_date, MTPint _offset_id, const MTPInputPeer &_offset_peer, MTPint _limit, MTPint _hash) : vflags(_flags), voffset_date(_offset_date), voffset_id(_offset_id), voffset_peer(_offset_peer), vlimit(_limit), vhash(_hash) {
  18.         }

  19.         uint32 innerLength() const;
  20.         mtpTypeId type() const {
  21.                 return mtpc_messages_getDialogs;
  22.         }
  23.         void read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_messages_getDialogs);
  24.         void write(mtpBuffer &to) const;

  25.         using ResponseType = MTPmessages_Dialogs;
  26. };
  27. using MTPmessages_GetDialogs = MTPBoxed<MTPmessages_getDialogs>;
复制代码
在程序中找对 MTPmessages_GetDialogs 的调用


         LongChat.exe!DialogsWidget::loadDialogs() 行 967        C++
>        LongChat.exe!DialogsWidget::{ctor}::__l2::<lambda>() 行 236        C++






3b9aca24
作者: Qter    时间: 2020-3-20 14:44
此类在线程中发送请求
ConnectionPrivate::ConnectionPrivate(..){
moveToThread(thread);

//通过信号槽,编程接收完数据后,通知到主线程中的类中
  1.         connect(thread, &QThread::started, this, [=] { connectToServer(); });
  2.         connect(thread, &QThread::finished, this, [=] { finishAndDestroy(); });
  3.         connect(this, SIGNAL(finished(internal::Connection*)), _instance, SLOT(connectionFinished(internal::Connection*)), Qt::QueuedConnection);

  4.         connect(sessionData->owner(), SIGNAL(authKeyCreated()), this, SLOT(updateAuthKey()), Qt::QueuedConnection);
  5.         connect(sessionData->owner(), SIGNAL(needToRestart()), this, SLOT(restartNow()), Qt::QueuedConnection);
  6.         connect(this, SIGNAL(needToReceive()), sessionData->owner(), SLOT(tryToReceive()), Qt::QueuedConnection);
  7.         connect(this, SIGNAL(stateChanged(qint32)), sessionData->owner(), SLOT(onConnectionStateChange(qint32)), Qt::QueuedConnection);
  8.         connect(sessionData->owner(), SIGNAL(needToSend()), this, SLOT(tryToSend()), Qt::QueuedConnection);
  9.         connect(sessionData->owner(), SIGNAL(needToPing()), this, SLOT(onPingSendForce()), Qt::QueuedConnection);
  10.         connect(this, SIGNAL(sessionResetDone()), sessionData->owner(), SLOT(onResetDone()), Qt::QueuedConnection);
复制代码
}


作者: Qter    时间: 2020-3-28 15:52
本帖最后由 Qter 于 2020-3-28 16:53 编辑

左侧dialogs更新机制
void MainWidget::createDialog(Dialogs::Key key)

         LongChat.exe!Dialogs::Entry::setChatListExistence(bool exists) 行 96        C++
         LongChat.exe!Dialogs::Entry::updateChatListSortPosition() 行 87        C++
         LongChat.exe!Dialogs::Entry::setChatListTimeId(int date) 行 146        C++
         LongChat.exe!History::setChatListMessage(HistoryItem * item) 行 2201        C++
         LongChat.exe!History::setChatListMessageFromLast() 行 2267        C++
         LongChat.exe!History::requestChatListMessage() 行 2282        C++
         LongChat.exe!History::setLastMessage(HistoryItem * item) 行 2179        C++
         LongChat.exe!History::addNewItem(gsl::not_null<HistoryItem *> item, bool unread) 行 999        C++
         LongChat.exe!History::addNewToLastBlock(const MTPBoxed<MTPmessage> & msg, NewMessageType type) 行 657        C++
         LongChat.exe!History::addNewMessage(const MTPBoxed<MTPmessage> & msg, NewMessageType type) 行 640        C++
         LongChat.exe!Data::Session::addNewMessage(const MTPBoxed<MTPmessage> & data, NewMessageType type) 行 1465        C++
         LongChat.exe!ApiWrap::applyUpdateNoPtsCheck(const MTPBoxed<MTPupdate> & update) 行 3577        C++
         LongChat.exe!PtsWaiter::updateAndApply(ChannelData * channel, int pts, int count, const MTPBoxed<MTPupdate> & update) 行 127        C++
         LongChat.exe!MainWidget::ptsUpdateAndApply(int pts, int ptsCount, const MTPBoxed<MTPupdate> & update) 行 3111        C++
         LongChat.exe!MainWidget::feedUpdate(const MTPBoxed<MTPupdate> & update) 行 3906        C++
         LongChat.exe!MainWidget::feedUpdateVector(const MTPBoxed<MTPvector<MTPBoxed<MTPupdate>>> & updates, bool skipMessageIds) 行 2858        C++
         LongChat.exe!MainWidget::feedUpdates(const MTPBoxed<MTPupdates> & updates, unsigned __int64 randomId) 行 3774        C++
>        LongChat.exe!MainWidget::updateReceived(const int * from, const int * end) 行 3749        C++


_mtproto->setUpdatesHandler(::rpcDone([](
                        const mtpPrime *from,
                        const mtpPrime *end) {
                if (const auto main = App::main()) {
                        main->updateReceived(from, end);
                }
        }));








欢迎光临 firemail (http://firemail.wang:8088/) Powered by Discuz! X3