Skip to content
Zoë Lynn edited this page Aug 9, 2020 · 11 revisions

The goal of this tutorial is to show how to handle the message that comes from the client-side.


A message handler is a function that receives a TCP protocol and tries to decode and process the message data.


1. First of all, we need to define the message-id for communicating between client-side and game server before we start (Now NF has done this for you.)

{ServerProject}/NFComm/NFMessageDefine/NFDefine.proto

	REQ_LOGIN								= 101;     	//
	ACK_LOGIN								= 102;     	//

2. Besides, we need to define a message structure to describe what is that message's content (Now NF has done this for you.)

{ServerProject}/NFComm/NFMessageDefine/NFMsgPreGame.proto

message ReqAccountLogin
{ 
    bytes 			account = 2;
    bytes 			password = 3;
    bytes 			security_code = 4;
    bytes 			signBuff = 5;
    int32 			clientVersion = 6;
    ELoginMode		        loginMode = 7;
    int32 			clientIP = 8;
    int64 			clientMAC = 9;
    bytes 			device_info = 10;
    bytes 			extra_info = 11;
    int32 			platform_type = 12;
}


3. In addition, we need to generate C++ code and C# code from IDL(Now protocol-buf)

  • Run the script "NFComm/NFMessageDefine/cpp.bat" and "NFComm/NFMessageDefine/cs.bat" (cpp.sh cs.sh) to generate the source code
  • Copy the source code files from {ServerProject}/_Out/NFDataCfg/client/ to the folder {ClientProject}/Assets/Resources/NFDataCfg/

4. Equally important, add a module for the login system. (Now NF has done this: {ServerProject}/NFServer/NFLoginNet_ServerPlugin/NFLoginNet_ServerModule)


5. Last but not least, add an observer(or call it as a watchdog?) for that message-id we defined at step 1

bool NFLoginNet_ServerModule::AfterInit()
{
	m_pNetModule->AddReceiveCallBack(NFMsg::REQ_LOGIN, this, &NFLoginNet_ServerModule::OnLoginProcess);
	return true;
}

void NFLoginNet_ServerModule::OnLoginProcess(const NFSOCK nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	NFGUID nPlayerID;
	NFMsg::ReqAccountLogin xMsg;
	if (!m_pNetModule->ReceivePB( nMsgID, msg, nLen, xMsg, nPlayerID))
	{
		return;
	}

	NetObject* pNetObject = m_pNetModule->GetNet()->GetNetObject(nSockIndex);
	if (pNetObject)
	{
		if (pNetObject->GetConnectKeyState() == 0)
		{
			//Normally, you could check the account and password is correct or not, but for our situation, it will correct by default as here is the tutorial code.
			int loginResult = 0;//0 means successful, else means error code from account platform.
			if (0 != loginResult)
			{
				std::ostringstream strLog;
				strLog << "Check password failed, Account = " << xMsg.account() << " Password = " << xMsg.password();
				m_pLogModule->LogError(NFGUID(0, nSockIndex), strLog, __FUNCTION__, __LINE__);

				NFMsg::AckEventResult xMsg;
				xMsg.set_event_code(NFMsg::ACCOUNTPWD_INVALID);

				m_pNetModule->SendMsgPB(NFMsg::EGameMsgID::ACK_LOGIN, xMsg, nSockIndex);
				return;
			}

			pNetObject->SetConnectKeyState(1);
			pNetObject->SetAccount(xMsg.account());

			NFMsg::AckEventResult xData;
			xData.set_event_code(NFMsg::ACCOUNT_SUCCESS);

			//The login server responds the login result to the player by sock id.
			m_pNetModule->SendMsgPB(NFMsg::EGameMsgID::ACK_LOGIN, xData, nSockIndex);

			m_pLogModule->LogInfo(NFGUID(0, nSockIndex), "Login succeeded :", xMsg.account().c_str());
		}
	}
}


In terms of client-side.

That's all.

Clone this wiki locally