Erlang遊戲開發-協議

Erlang遊戲開發-協議

選擇什麼協議?

協議包含通訊協議和數據格式.

通訊協議

通訊協議目前常用的是:HTTPTCP .其有各自的特點根據遊戲的特點而進行選擇.

HTTP

HTTP比較成熟,使用極其廣泛.具有豐富的基礎軟件和工具.
對於簡單的social game可以使用HTTP作爲通訊協議.
這類遊戲對實時性要求不是很高,使用HTTP也很容易做到性能擴展,可以較好的滿足需求.
如果遊戲前端使用HTML+js開發,那麼只能使用HTTP了,需要較好的交互性和實時性時,只能
使用HTTP長輪詢來實現了.如果前端使用flash開發,遊戲交互複雜,實時性要求高,那麼HTTP
便不合適了.

TCP

HTTP是高級的應用協議,而TCP便是比較基礎的協議了.HTTP也是基於TCP實現.
對於一些web game,基本上採用TCP.其併發量不大(單服web game通常在線千人左右),而
實時性要求很高,尤其是ARPG遊戲.因此TCP是不二選擇.其前端大多使用flash實現(因爲
HTML5之前,html+js無法創建TCP socket).至於非80,非443端口的防火牆問題,貌似現在
的網絡環境下可以忽略.

數據格式

文本格式,比如xml,json或自定義均可作爲傳輸的數據格式,文本格式最大的好處是可讀,
便於調試,缺點是數據量比較大,冗餘信息太多.(當然可以通過壓縮來彌補).因此在web
game中很少使用文本作爲數據傳輸格式.

 

除卻文本就是二進制協議了.二進制協議也分多種:protobuf,thrift等通用二進制傳輸協議和
自定義二進制格式.使用protobuf和thrift的好處是通用性,多種語言均支持,再一個規模比較
大,使用多種開發語言的環境中比較合適.作爲web game,通常是一個工作室負責一款產品,
client和server使用的技術和語言相對確定,因此這些通用二進制傳輸協議就不是最好的選擇,
同時,其因爲通用,也導致了一些性能下降. 

 

目前大部分遊戲是採用自定義二進制協議,基本結構爲:頭部幾個字節表示數據體長度,隨後爲
數據體.在數據體中,可以劃分出幾個字節(如2個)表示某種消息.我們會爲每種消息都定義數據
格式. 其大致的樣子如下: [2字節數據長度][2字節消息類型,具體的消息體].

Erlang中如何處理?

再Erlang中實現這樣的協議非常簡單, 設置inet:setopts/2的  packet 選項爲2,便可支持我們上面
的協議.Erlang自動會首先獲取2個字節,作爲長度,隨後繼續接受數據,知道這個包接收完成,
省去了我們自己處理解包,粘包的痛苦 :)(注意2個自己使用無符號的big-endian編碼方式).
有了數據體,接下來需要處理2個字節的消息類型,Erlang還提供了一個貼心的選項:{header , size}(注意這個選項只有在socket設置binary選項的時候有效).再這裏我們設置{header, 2},這樣我們收到的數據體,不是一整塊,而是這樣:[Byte1, Byte2 | Binary],Byte1,Byte2是Erlang爲我們截取出的數據體的頭2個字節. 對於熟悉Erlang的朋友,我提一個問題:
這個數據是格式規則的列表麼?答案是No,這個列表是一個"畸形"的列表,因爲其最後一個元素不是列表.有些繞遠了... :(

 

還有,在Erlang中TCP,擁有一個active 選項,其取值爲:true, false, once.看過書的都明白,其是用來控制TCP數據的接收方式.通過使用 inet:setopts(Sock, [{active, once}]),我們可以讓數據乖乖的聽話,主動發給我們一個數據,然後變不主動,我們處理完這個消息後,然後在設置active once,其繼續再發給我們一個數據. 這樣的好處是,不會因爲{active, true},給我們發送了大量的數據,導致我們應接不暇.也不會讓我們每次都手動 gen_tcp:recv/2數據,那麼累人. 

 

遊戲中協議的消息類型達上百中,這個過程如果手工編碼會非常累,應該在開始的時候,再確定好協議格式後,就書寫腳本完成協議編解碼的自動生成,一勞永逸!大大減少調試出錯的可能.協議修改後,通過一個命令就可以重新生成代碼.非常happy.(有的團隊,更加geek,直接使用erlang:term_to_binary作爲二進制協議,由flash端進行erlang term的解析,非常強大).

 

最後就是要動手,首先把網絡和協議搞定,遊戲之路就開始了 :)

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