*** Understanding Chat Flow ***
0. 杂想杂问
1. CChatMainDlg
CChatComponent m_component;
CChatSession m_session;
onBtnSend() -> m_session.SendChatData();
* Sendata()
void CChatMainDlg::SendData(BOOL bPublic, CString& cSender, CString& cMessage)
{
if (m_chatsession.IsConnect())
{
CHARFORMAT cf;
cf.cbSize = sizeof(CHARFORMAT);
cf.dwMask = CFM_CHARSET | CFM_FACE;
m_input.GetDefaultCharFormat(cf);
CChatDataPdu pdu;
pdu.m_bPublic = bPublic;
pdu.m_cSender = cSender;
pdu.m_cMessage = cMessage;
pdu.m_bChatSet = cf.bCharSet;
pdu.m_cFaceName = cf.szFaceName;
CRtMessageBlock aData(pdu.GetLength());
pdu.Encode(aData);
int nLen = pdu.GetLength();
LPCSTR lpData = aData.GetTopLevelReadPtr();
if (bPublic == FALSE && m_bPublic == FALSE)
{
InfoUser_ID user(m_idChatUser);
m_chatsession.SendChatData(nLen, (const LPBYTE)lpData, &user);
}
else
{
m_chatsession.SendChatData(nLen, (const LPBYTE)lpData);
}
}
}
Q:只在这里涉及MessageBlock,底层不再涉及?底层只涉及指针与长度?
2. CChatSession
class CChatSession : public ISessionClientSink
{
...
protected:
CRtAutoPtr<ISessionClient> m_pSession;
CChatMainDlg& m_chatDlg;
CInfoRosterInfo m_userInfo;
InfoChannel_ID m_Channel_All;
InfoChannel_ID m_Channel_AllUser;
InfoChannel_ID m_Channel_AllLocalPort;
CSessRosterList m_userMgr;
DWORD m_dwStatus;
}
Q: Why没有实现ISeessionClient接口,而是有一个成员变量m_pSession?
CmResult CChatSession::InitSession(ISessionClient* pSession)
{
RT_ASSERTE(m_pSession == NULL);
if (m_pSession)
return CHAT_SESS_ALREADY_EXIST;
CmResult rt = CHAT_SESS_CALL_FAIL;
m_pSession = pSession;
RT_ASSERTE(m_pSession);
if (m_pSession)
rt = m_pSession->OpenWith(this);
return rt;
}
Q: ISessionClient的实现类究竟有哪些?只有CConfSession?
3. ISessionClient
virtual RtResult SendData(
const InfoChannel_ID& destID,
DATA_Priority priority,
DATAFLAG dataFlag, // What's this ?
DWORD length,
const LPBYTE lpData) = 0;
4. CConfSession
RtResult CConfSession::SendData(
const InfoChannel_ID& destID,
DATA_Priority priority,
DATAFLAG dataFlag,
DWORD length,
const LPBYTE lpData)
{
...
if (length > 8 * 1024)
{
RT_WARNING_TRACE_THIS("CConfSession::SendData, sess type="<<m_sessKey.nSessionType<<": pdu too long! len="
<<length<<",dataFlag="<<dataFlag<<",destID="<<destID);
}
...
return SendData_i(destID, priority, dataFlag, length, lpData);
}
RtResult CConfSession::SendData_i(...)
{
LPBYTE lpOutData = lpData;
DWORD outLength = length;
if (m_sessSecurity)
{
EncryptData_i(lpData, length, lpOutData, outLength,
m_securityBuff, m_securityBlen);
}
return SessSenddData(destID, priority, dataFlag, outLength, lpOutData);
}
RtResult CConfSession::SessSenddData(...)
{
CRtMessageBlock aData(
length, (LPCSTR)lpData, CRtMessageBlock::DONT_DELETE, length);
CInfoSvrSessApplicationData pdu(
GetUserID(), destID, priority, dataFlag, aData);
return m_conference.SendData(&pdu, priority, dataFlag);
}
Q:Why会从CConference发出最终信息?这里的PDU干嘛的?
5. CInfoSID
Q:如何理解?