UC故事2011/11/20 - 1

来源:互联网 发布:linux find查找字符串 编辑:程序博客网 时间:2024/05/17 00:57


### 研究Chat实现 ###


1. 研究目标

*  Chat模块被load的全过程

* Chat消息发送过程

* Chat消息接收过程


2. WinMain() of ConfMain

launch rtTracespy.exe(Q:Why not see 任务管理器?

load rtDiagnose.dll

load rtConfClient.dll(主程序)

启动rtDiagnose.dll调试(Q:与TraceSpy.exe之关系?实际做了什么东东?为什么thread pool的启动会放在这里?

调用rtConfCient的LaunchConf

停止调试


3. ConfClient:: LaunchConf

创建Mutex(用于控制只有一个ConfMain出现,but Why ?)

初始化ATL环境

load riched32.dll(why ?)

load rtConfRes.dll并设置_Module(_Module.m_hInstResource = ::LoadLibrary(szDllPath);)

Call Run():生成主窗口并进入消息循环

释放ATL

释放Mutex


4. ConfClient::Run

实例化MessageLoop对象并加入_Modue

实便化CConfManage,并据此生成MainFrame对象

load infowarelab.ini

主窗口调用CreateEx

显示主窗口

进入消息循环

     CMainFrame::OnCreate被调用(实现了线程初始化、Conference建立等功能,与Server会有N多次交互 ,代码在CConfManage::CreateConference(),2011/12/04

销毁对象, 退出


5. CMainFrame::OnCreate

实例化CConfClientView并调用create(具体做了什么东东?

把_Modue中的MessageFilter指向CConfClientView

PrepareSession()

ConfManage::CreateConference()  // 这里做了LeaveConference/CreateConference/Join Conference三个动作。


6. CMainFrame::PrepareSession()

根据m_ConfManage.m_ConfCreateInfo.dwSessionLoad的值设置哪些session需要create:m_ConfManage.m_ConfCreateInfo.pSessionCreateInfo

Q:这个dwSessionLoad的值是根据什么设置的?where?(应该来源于infowarelab.ini中的ConfRights=1048576)


7. MainFrame::CreateEx


总结:在目前为止发现,当进入MessageLoop.run()以后,才出现chat.dll被加载。这就意味着,chat.dll的加载是由某个消息引起的。

2011/12/04,再次总结:实际上是在CMainFrame.OnCreate()中完成了Thread初化及Conference Creation,其间会有Component的Create,引起DLL的load。


8. CConfMain::CreateComponent()

函数头设断点,statck的内容如下:

CConfManage::CreateComponent(const CSessionKey & {...}, const CRtString & {0x0205ac41 ""}, ISessionClient * 0x02066f40, const CInfoSID & {...}) line 2650

CConfManage::OnSessionCreateConfirm(int 0, const CSessionKey & {...}, const CRtString & {0x0205ac41 ""}, ISessionClient * 0x02066f40) line 874 + 30 bytes
CConference::HandleSessionCreateIndicate(CInfoSvrSessionCreateIndicatePdu * 0x0205fc90) line 1800 + 54 bytes
CConference::OnReceiveData(CRtMessageBlock & {...}) line 1404
CConfConnection::OnReceiveData(CRtMessageBlock & {...}, IConnection * 0x0205ff64) line 170
CRtIMConnection::OnReceive(CRtMessageBlock & {...}, IRtTransport * 0x0205eb18, CRtTransportParameter * 0x00000000) line 890 + 50 bytes
CRtEventOnReceive::OnEventFire() line 375 + 50 bytes
CRtEventQueueBase::ProcessOneEvent(IRtEvent * 0x020633f8) line 229 + 12 bytes
CRtEventQueueBase::ProcessEvents(const std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}) line 217
CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x00be0606, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
WTL::CMessageLoop::Run() line 468 + 15 bytes
Run(char * 0x00151f28, int 1) line 207 + 11 bytes
LaunchConf(HINSTANCE__ * 0x00400000, char * 0x00151f28, int 1) line 318 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 85 + 20 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()


从这里看,这是在响应SessionCreate

Q:SessionCreate是在什么时候发出的?


9. CManageBase::CreateComponentBase

这是真正完成component生成(加载)的地方


加载DLL

完成Component对session的attach及enroll


以下statement

if(InsertObject(hParent, GetDllPath().c_str(), sessType))

产生以下info:

Loaded symbols for 'E:\projects-workspace\box-4.2-UCP-4.5-0429\bin\dlls\Debug\rtchat.dll'
$20111120 09:45:59.890 19300/19296 info: CHAT MODULE LOADED ...... 
$20111120 09:45:59.890 19300/18520 WARN: CRtTransportTcp::Recv_i, recv() failed! fd=0xdf8 err=10053:您的主机中的软件放弃了一个已建立的连接。
 this=0x2074658
$20111120 09:45:59.890 19300/18520 info: CRtTransportBase::OnClose, fd=0xdf8 sink=0x2074514 this=0x2074658
$20111120 09:45:59.890 19300/18520 info: CRtConnRlbTcpClient::OnDisconnect, reason=20001 trpt=0x207465c status=5 this=0x2074510
$20111120 09:45:59.890 19300/18520 info: CRtReactorWin32Message::Win32SocketWndProc, handle is closed. fd=0xdf8 mask=0 nErrorCode=0 lParam=32 rvError=20003
$20111120 09:45:59.890 19300/18520 WARN: CRtReactorBase::ProcessHandleEvent, handle not registed. aFd=0xdf8 aMask=128 aReason=20003 rv=10011
$20111120 09:45:59.968 19300/19296 info: Chat AddUser, index: 0, id: 0, id: 0, Name: 没有人


总结:下一步搞清CreaeSession是什么时候发出的。


10. CConfManage::CreateAllSessions


CConfManage::CreateAllSessions() line 2911
CConfManage::OnConferenceJoinConfirm(int 0, const CInfoSID & {...}, const CInfoSID & {...}, const CInfoSID & {...}, unsigned long 1) line 788 + 11 bytes
CConference::HandleEnrollConfRspn(CInfoSvrEnrollConfRspnPdu * 0x0205d468) line 1597 + 79 bytes
CConference::OnReceiveData(CRtMessageBlock & {...}) line 1374


11. IConference::JoinConference 

Q:IConferfence的实现类?


12. CConfManage::CreateConference

CConfManage::CreateConference() line 2368

CMainFrame::OnCreate(unsigned int 1, unsigned int 1, unsigned int 1, unsigned int 1) line 1879
CMainFrame::ProcessWindowMessage(HWND__ * 0x00210c9a, unsigned int 1, unsigned int 0, long 1269856, long & -858993460, unsigned long 0) line 138 + 37 bytes


结论:在CMainFrame.OnCreate中,conference被创建。(6:30-10:30)


13. 几个重要类的关系

CConferenceManage::CreateConferece发起IConference实例

CConfProvider::CreateConference()完成实例的构造,并且向此IConference传递一个IConferenceSink(就是CConferenceManage本身)

CConfProvider实际为一个Factory.


INT CConfManage::CreateConference() 
{
   ......
   nResult = IConference::CreateInstance(m_ConfCreateInfo.confID, m_ConfCreateInfo.userInfo.GetImUserId(),this, m_pConference);
   ......
}


RtResult IConference::CreateInstance(

const ConfID_Type& confID, 
const CRtUserID& userID,
const IConferenceSink* aSink,
IConference*& outConference)
{
return CConfProvider::Instance()->CreateConference(
confID, userID, aSink, outConference);
}


Q:Why在workspace中找不到CConfProvider的定义?

   A:启用auto_build_client DSW,能找到,并且能到IConference的实现类CConference. VERY GOOD !

   把CONFCLI项目加入到当前DSW,可跟踪也。


Tips

* 断点管理:Edit/Break或^B或ALT+F9

* DLL中的断点要在DLL加载后生效。

* 主窗口显示完毕后,rtChat.dll已经被loaded。


14. ConfManage::CreateConference()


steps: 

Leave Conference // send PDU to server                                                   Q:真正传输了信息到Server端?如何完成的?经过中间哪些线程及类的方法处理?

IConference::CreateInstance(生成CConference实例)

Join Conference // send PDU to server


15. ConfManage::OnConferenceJoinConfirm()

STACK AS FOLLOWS:


CConfManage::OnConferenceJoinConfirm(int 0, const CInfoSID & {...}, const CInfoSID & {...}, const CInfoSID & {...}, unsigned long 1) line 325
CConference::HandleEnrollConfRspn(CInfoSvrEnrollConfRspnPdu * 0x0205e118) line 1597 + 79 bytes
CConference::OnReceiveData(CRtMessageBlock & {...}) line 1374
CConfConnection::OnReceiveData(CRtMessageBlock & {...}, IConnection * 0x0205ef94) line 170
CRtIMConnection::OnReceive(CRtMessageBlock & {...}, IRtTransport * 0x0205dd98, CRtTransportParameter * 0x00000000) line 890 + 50 bytes
CRtEventOnReceive::OnEventFire() line 375 + 50 bytes
CRtEventQueueBase::ProcessOneEvent(IRtEvent * 0x0205de30) line 229 + 12 bytes
CRtEventQueueBase::ProcessEvents(const std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}) line 217
CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x000700d0, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
WTL::CMessageLoop::Run() line 468 + 15 bytes
Run(char * 0x00151f28, int 1) line 207 + 11 bytes
LaunchConf(HINSTANCE__ * 0x00400000, char * 0x00151f28, int 1) line 318 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 85 + 20 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()



原创粉丝点击