### 研究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()