業餘寫個moba手遊系列之——連上服務器

希望這次的系列文章,我能堅持寫完啊…
先交代個背景。之前在A公司作爲校招生培訓時做了個moba手遊,覺得自個當時太年輕,小團隊不敢自個內部孵化,就跑去某半成品項目組了,自己的moba也就沒繼續去做了。現在跳槽到了B公司,B公司規模很大,但是每天也都是業務邏輯爲主,而且還是天天敲python。爲了不荒廢c++以及提升自己的技術棧,準備業餘時間重新把這款moba手遊搞起來。
服務器用的是A公司的LuaServer(校招時就有源碼在手,一直沒時間拜讀,現在正好結合B公司的技術進行融會貫通下,哈哈哈哈),客戶端用的Unity3D。
之前做這款手遊時是剛畢業,服務端代碼是拿來即用,直接用lua寫邏輯,對他們的底層並不瞭解,2年後,我現在準備重頭寫一遍,探探其原理,順便用博客記錄記錄這個過程,嘿嘿嘿。

之前開發時,Unity那邊用的是一個dll庫自動連接到LuaServer,現在既然跑到B公司了,也沒有那個dll的源碼,so,對於Unity那邊來說,第一步是要先實現一套與LuaServer配套的rpc網絡連接小框架了,爲了達到這個目的,我也必須去看看LuaServer的網絡是咋寫的。。。好了,於是,本文就出來了。
估摸着等整出個完全能用的客戶端連接代碼還是需要點時日的,不過不着急,畢竟是自個的業餘技術項目嘛,哈哈哈。今天從Git上搗鼓了一個c#的網絡連接庫HiSocket,用這個庫作爲基礎,開始慢慢搭。Git地址,有需要的自取。
OK,改改參數,先連上我的LuaServer再說,客戶端基於HiSocket實現了一個連上LuaServer後不斷髮送自增id的操作,看看LuaServer的後臺是否有反應。socket是連接上了,可一直提示包體長度非法是咋回事?按理說,我每次發送一個uint_32的數據,包體再怎麼樣也不會是67108864啊。。。

2019-04-20 15:46:26,619 INFO CAsioSessionIn.Go - Accepted connection. Remote=127.0.0.1:51370. Session_11.
2019-04-20 15:48:34,403 WARN CAsioSessionBase.Read - Illegal len: 67108864

好了,爲了解決這個問題,必須去看源碼了。好在2年的服務端工作經驗告訴我,對於還沒看過源碼的,最快debug的方式就是斷點調試咯。兩邊分別斷在收發消息的地方。
客戶端代碼如下:

	public void Pack(IByteArray source, Action<byte[]> packedHandler)
	{
		// Add head length to your message(use int, 4 byte as head)
		var length = source.Length;
		var head = BitConverter.GetBytes(length);
		source.Insert(0, head);// add head bytes
		var packed = source.Read(source.Length);
		packedHandler(packed);
	}

服務端代碼如下:

	ReadBuf buf;
	uint32_t dwLenNet;
	using namespace boost::asio;
	boost::system::error_code ec;
	std::size_t uReadHead = async_read(rSocket,
		buffer(&dwLenNet, sizeof(dwLenNet)), yield[ec]);
	// 省略一些邏輯...
	uint32_t dwLenHost = ntohl(dwLenNet);
	if (dwLenHost > MAX_DATA_LEN)
	{
		LOG_WARN_TO("CAsioSessionBase.Read", "Illegal len: " << dwLenHost);
		return false;
	}

問題就出在客戶端每次明明都是把長度寫在了包頭,爲啥服務器取出來的dwLenHost 值都是異常的呢???搗鼓了半天,總算醒悟過來,服務端的dwLenHost 是調用了ntohl之後的值,也就是說,默認發過來的dwLenNet應該是網絡字節序,而我客戶端發送的並沒有把本地字節轉成網絡字節,導致兩邊的行爲不一致。。。
找到了問題後就好辦了,修改客戶端代碼爲:

	public void Pack(IByteArray source, Action<byte[]> packedHandler)
    {
        // Add head length to your message(use int, 4 byte as head)
        var length = IPAddress.HostToNetworkOrder(source.Length);
        var head = BitConverter.GetBytes(length);
        source.Insert(0, head);// add head bytes
        var packed = source.Read(source.Length);
        packedHandler(packed);
    }

上面的問題果然順利解決,此時LuaServer的日誌爲:

2019-04-20 16:25:59,922  WARN CAsioSessionBase.HandleData  - Got illegal RpcPackage, len=4

這提示是RPC數據問題,這現在要是沒問題纔是大問題呢,由於LuaServer用的都是protobuf作爲數據通信協議,下一步客戶端就要開始基於protobuf進行數據加工。至此,第一步,連上服務器算是搞定了。
鼓掌~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章