网狐架构之客户端大厅与客户端子游戏(斗地主)

客户端大厅与客户端子游戏斗地主交互过程

1:启动:CDlgLogon::OnInitDialog()
2:登录:CDlgLogon::OnOK()
3:游戏列表中点击游戏响应
CServerListView::OnNMLClick(NMHDR * pNMHDR, LRESULT * pResult)
连接127.0.0.1 1372端口的游戏服务器(注意此处的游戏服务房间IP PORT为在大厅登录完成时进入获取游戏列表的第四次循环时填充),此端口为游戏服务端随机,客户端连接时会获取
if (m_TCPSocketModule->Connect(m_GameServer.szServerAddr,m_GameServer.wServerPort)!=CONNECT_SUCCESS)

4:网络相关的消息客户端响应处
LRESULT CTCPSocket::OnSocketNotify(WPARAM wParam, LPARAM lParam)
此函数为一个while循环,while (m_wRecvSize>=sizeof(TCP_Head))
时,一直循环调用m_pITCPSocketSink->OnEventTCPSocketRead
(注意:m_pITCPSocketSink为ITCPSocketSink类型,此类型为父类,利用多态调用具体各功能子类类型)
||
CMissionSocket::OnEventTCPSocketRead
m_pIMissionSocketSink->OnEventMissionRead
(注意:IMissionSocketSink为IMissionSocketSink类型,此类型为父类,利用多态调用具体各功能子类类型)
||
CMissionManager::OnEventMissionRead
for (INT_PTR i=0;i {
CMissionItem * pMissionItem=m_MissionItemArray[i];
pMissionItem->OnEventMissionRead(Command,pData,wDataSize);
}

上面CMissionItem为一个父类,会派生出很多功能的子类,子类都实现OnEventMissionRead
函数,会利用多态根据pMissionItem的具体类型调用函数实现。其中CMissionItem的父类中的IMissionSocketSink函数为纯虚函数

5:进入房间
创建桌子bool CTableViewFrame::ConfigTableFrame
||
点击桌子座位时
VOID CTableViewFrame::OnLButtonUp(UINT nFlags, CPoint MousePoint)
在此函数中最终调用下面函数发送坐下请求
m_TCPSocketModule->SendData(MDM_GR_USER,SUB_GR_USER_SITDOWN,&UserSitDown,sizeof(UserSitDown));
CTCPSocket::SendData(WORD wMainCmdID, WORD wSubCmdID, VOID * pData, WORD wDataSize)

游戏 (装载)服务器响应在case SUB_GR_USER_SITDOWN: //用户坐下
校验桌子相关信息,如能否坐下,金币是否足够,桌子是否已开局等信息,
pTableFrame->PerformSitDownAction(wRequestChairID,pIServerUserItem,pUserSitDown->szPassword);
校验通过执行
pIServerUserItem->SetUserStatus(US_SIT,m_wTableID,wChairID);
m_pIServerUserItemSink->OnEventUserItemStatus(this,wOldTableID,wOldChairID);
设置用户坐下状态通知大厅,
SendData(BG_COMPUTER,MDM_GR_USER,SUB_GR_USER_STATUS,&UserStatus,sizeof(UserStatus));
然后群发此用户的信息至此桌子所在的地方通知

然后在
CTCPSocket::OnSocketNotifyRead(WPARAM wParam, LPARAM lParam)
的响应中
CPlazaUserManager::UpdateUserItemStatus
m_pIUserManagerSink->OnUserItemUpdate(pIClientUserItem,UserStatus);
CServerViewItem::OnUserItemUpdate
m_ProcessManager.CreateGameProcess(m_GameKind.szProcessName);//启动进程LandHappy.exe客户端
切启动参数为传入 “LandHappyD.exe /Transmittal:460748”,其中游戏客户端响应函数CClientKernel::InitClientKernel(LPCTSTR lpszComLine)
接受传入参数
6:点击开始(大厅消息处理)
CTCPSocket::OnSocketNotifyRead(WPARAM wParam, LPARAM lParam)
||
CServerViewItem::OnUserItemUpdate
m_ProcessManager.SendUserStatus(pUserInfo->dwUserID,UserStatus);
||
CProcessControl::SendData(HWND hWndServer, WORD wMainCmdID, WORD wSubCmdID, VOID * const pData, WORD wDataSize)
::SendMessage(hWndServer,WM_COPYDATA,(LPARAM)m_hWnd,(WPARAM)&CopyDataStruct);

7:点击开始(游戏客户端给大厅发送消息)
CGameClientView::OnBnClickedStart()
||
CGameClientEngine::OnMessageStart(WPARAM wParam, LPARAM lParam)
m_pIClientKernel->SendUserReady(pData,wDataSize);
SendSocketData(MDM_GF_FRAME,SUB_GF_USER_READY,pData,wDataSize);
m_ProcessControlModule->SendData(m_hProcessWnd,IPC_CMD_GF_SOCKET,IPC_SUB_GF_SOCKET_SEND,&SocketSend,wSendSize);
向大厅发送准备消息(1)

大厅响应
CProcessControl::OnMessageAsynchronismData(WPARAM wParam, LPARAM lParam)
接受游戏客户端准备消息响应后向m_hSocket(游戏服务器)发送准备消息,(2)
m_pIProcessControlSink->OnProcessControlData
m_pIProcessManagerSink->OnProcessManagerData
m_TCPSocketModule->SendData(pCommand->wMainCmdID,pCommand->wSubCmdID);
CTCPSocket::SendDataBuffer
send(m_hSocket,(char *)pBuffer+wSended,wSendSize-wSended,0);
send为winsock的库函数,此阶段向游戏服务发送消息走网络服务TCPSocket。且m_hSocket为点击大厅游戏列表进入房间时连接的游戏服务器

大厅接受游戏服务器消息回应(3)
CTCPSocket::OnSocketNotify
OnSocketSubUserStatus(pData,wDataSize);
m_PlazaUserManagerModule->UpdateUserItemStatus(pIClientUserItem,&pUserStatus->UserStatus);
m_pIUserManagerSink->OnUserItemUpdate(pIClientUserItem,UserStatus);
SendProcessData(IPC_CMD_GF_USER_INFO,IPC_SUB_GF_USER_STATUS,&UserStatusData,sizeof(UserStatusData));
m_ProcessControlModule->SendData(m_hProcessControl,wMainCmdID,wSubCmdID,pData,wDataSize);
::SendMessage(hWndServer,WM_COPYDATA,(LPARAM)m_hWnd,(WPARAM)&CopyDataStruct);
向游戏客户端发送用户状态,此函数处于进程控制CProcessControl中,即走windows消息机制中(5)

8:大厅给游戏客户端发送消息,
m_ProcessControlModule->SendData(m_hProcessControl,wMainCmdID,wSubCmdID,pData,wDataSize);

游戏客户端响应
CProcessControl::OnMessageAsynchronismData(WPARAM wParam, LPARAM lParam)
m_pIProcessControlSink->OnProcessControlData
m_GameUserManagerModule->UpdateUserItemStatus
m_pIUserManagerSink->OnUserItemUpdate
pIUserEventSink->OnEventUserStatus(pIClientUserItem,bLookonUser);
客户端显示准备提示,完成游戏客户端准备过程(6)

9:游戏客户端 启动时,大厅服务器会响应
CProcessControl::OnMessageAsynchronismData(WPARAM wParam, LPARAM lParam)
CProcessManager::OnProcessControlData
case IPC_SUB_GF_CLIENT_READY: //准备就绪
此处实现会将游戏客户端的句柄保存
m_hProcessControl=hWndSend;,用于后续给游戏客户端发送消息

总结如下:
从子游戏客户端点击开始,到大厅,在到游戏服务器,再到大厅,再到游戏客户端显示准备提示,完成了准备过程。
游戏大厅与游戏客户端通信,处于公共组件-进程控制(CProcessControl
)中,采用windows消息机制,调用::SendMessage函数实现,
而接受方处于ON_MESSAGE(WM_ASYNCHRONISM_DATA,OnMessageAsynchronismData)
函数
大厅到游戏服务器采用Socket通信。

你可能感兴趣的:(服务架构分析)