protobuf消息定義原則_第1頁
protobuf消息定義原則_第2頁
protobuf消息定義原則_第3頁
protobuf消息定義原則_第4頁
protobuf消息定義原則_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、錄- 1. 使用 protobuf 的enum定于消息的編號,也就是消息的類型。 2. 會為每個具有消息體的消息定義一個對應(yīng)的protobuf message。例如Login_Request會有一個對應(yīng)LoginRequest消息。 3. 會為每個消息大類定義一個消息,例如命令消息全部包含在message Command中,請求消息全部包含在Request消息中,應(yīng)答消息全部包含在Response消息中,指示消息全部包含在Indication消息中。 4. 對于應(yīng)答消息,并非總是成功的,因此在應(yīng)答消息中還會包含另外2個字段。一個用于描述應(yīng)答是否成功,一個用于描述失敗時的字符串信息。 對于有多個

2、應(yīng)答的消息來說,可能會包含是否為最后一個應(yīng)答消息的標(biāo)識。應(yīng)答的序號(類似與網(wǎng)絡(luò)數(shù)據(jù)包被分包以后,協(xié)議要合并時,需要知道分片在包中的具體位置)。因此Response看起來想這樣: 5. 最后我會定義一個大消息,把Command、Request、Response、Indication全部封裝在一起,讓后在通信的時候都動大消息開始編解碼。大消息看起來想下面這樣。 6. 發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。 6. 消息處理(C+) 7. wireshark抓包1網(wǎng)絡(luò)通信涉及到消息的定義,不管是使用二進(jìn)制模式、xml、json等格式。消息都可以大體的分為 命令消息、請求消息、應(yīng)答消息和指示消息4大消息類型。一般情況下每

3、個消息還還有包含一個序列號和一個能夠唯一區(qū)分類型類型的消息編號,編號可以使用字符串、整數(shù)或者枚舉等。1. 使用 protobuf 的enum定于消息的編號,也就是消息的類型。我會為每個系統(tǒng)都定義一個MSG枚舉。包含系統(tǒng)用到的所有消息的枚舉編號01enumMSG0203Login_Request = 0x;04Login_Response = 0x;0506XXX_Request = 0x;07XXX_Request = 0x;0809XXX_Command = 0x;1011XXX_Indication = 0x;122. 會為每個具有消息體的消息定義一個對應(yīng)的protobuf message

4、。例如Login_Request會有一個對應(yīng)LoginRequest消息。1message LoginRequest23required bytes username = 1;4required string password = 2;53. 會為每個消息大類定義一個消息,例如命令消息全部包含在message Command中,請求消息全部包含在Request消息中,應(yīng)答消息全部包含在Response消息中,指示消息全部包含在Indication消息中。也就是我會有下面4個protobuf message:01message Command02/ 包含所有的 XXXCommand 消息0304

5、message Request05/ 包含所有的 XXXRequest消息0607message Response08/ 包含所有的Response消息0910message Indication11/ 包含所有的Indication消息。124. 對于應(yīng)答消息,并非總是成功的,因此在應(yīng)答消息中還會包含另外2個字段。一個用于描述應(yīng)答是否成功,一個用于描述失敗時的字符串信息。 對于有多個應(yīng)答的消息來說,可能會包含是否為最后一個應(yīng)答消息的標(biāo)識。應(yīng)答的序號(類似與網(wǎng)絡(luò)數(shù)據(jù)包被分包以后,協(xié)議要合并時,需要知道分片在包中的具體位置)。因此Response看起來想這樣:1message Response2

6、3requiredboolresult = 1;4optional bytes error_description = 2;5requiredboollast_block = 3;6required fixed32 block_index = 4;7./其他的字段為 XXXResponse.85. 最后我會定義一個大消息,把Command、Request、Response、Indication全部封裝在一起,讓后在通信的時候都動大消息開始編解碼。大消息看起來想下面這樣。01message Message0203required MSG type = 1;04required fixed32 s

7、equence = 2;0506optional Request request = 3;07optional Response response = 4;08optional Command command = 5;09optional Indication indication = 6;106. 發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。用于UDP的時候比較簡單,因為每個數(shù)據(jù)包就是一個獨(dú)立的Message消息,可以直接解碼,或者編碼后直接發(fā)送。但是如果是使用于TCP的時候,由于涉及到粘包、拆包等處理,而且Message消息里面也沒有包含長度相關(guān)的字段(不好處理),因此把Message編碼后的消息嵌入另外一個二進(jìn)

8、制消息中。使用4字節(jié)消息長度+Message(二進(jìn)制數(shù)據(jù))+(2字節(jié)CRC校驗(可選)其中4字節(jié)的內(nèi)容,只包含Message的長度,不包含自身和CRC的長度。如果需要也可以包含,當(dāng)要記得通信雙方必須一致。6. 消息處理(C+) 編解碼后,根據(jù)Message.type字段,可以知道要處理的消息,進(jìn)行分發(fā)。不過一般情況下我不喜歡if、switch。所以我比較傾向于使用虛函數(shù)來處理。因此一般情況下我會定義一下的處理方法。01#pragma once0203#include 04#include 05#include 0607#include Client.h0809usingstd:shared_p

9、tr;1011classBaseHandler1213public:14BaseHandler(pbmsg:MSG type):type_(type)15Register (this);1617virtualBaseHandler()1819pbmsg:MSG GetType()constreturntype_; 20/具體處理方法,由派生類實現(xiàn).21virtualvoidProcess(constshared_ptr & msg,constshared_ptr & client) = 0;2223/注冊消息處理方法24staticvoidRegister( BaseHandler *);25

10、/執(zhí)行指定的消息,查詢處理方法,調(diào)用Process。26staticvoidExecute(constshared_ptr & msg,constshared_ptr & client);27private:28pbmsg:MSG type_;293031private:32staticstd:map handers;33;34/ 每個消息都實現(xiàn)Process的一個特化版本.35template36classMessageHandler :publicBaseHandler3738public:39MessageHandler(void):BaseHandler(Type)40MessageH

11、andler(void)4142voidProcess(constshared_ptr & msg,constshared_ptr & client);43private:44staticMessageHandler thisHandler;4546;474849/放在.cpp.cxx文件中.5051voidBaseHandler:Register( BaseHandler * h )5253handersh-GetType () = h;54555657voidBaseHandler:Execute(constshared_ptr & msg , .其它參數(shù))5859auto it = ha

12、nders.find(msg-type();60if( it != handers.end ()6162 it-second-Process(msg,client);63else64 LOG(ERROR) 消息 type() 沒有對應(yīng)的處理方法.n;656611/對每個MSG 枚舉的消息值,都會特化一個Process方法。1template2voidMessageHandler:Process(constshared_ptr & msg , .其它參數(shù))1/并且在全局空間創(chuàng)建對象,系統(tǒng)啟動時,自動創(chuàng)建。如果需要在堆空間中分配,另行封裝方法,并調(diào)用下面的代碼,讓編譯器實例化類。01Message

13、Handler MessageHandler:thisHandler;020304050607080910111213140102/最后消息處理:非常的easy:03040506shared_ptr recvMessage(newpbmsg:Message();07boolparserOk = recvMessage-ParseFromArray(msg.rd_ptr ()+4), msg.size ()-4);08if( parserOk )0910BaseHandler:Execute (recvMessage, .其它參數(shù));1112137. wireshark抓包 protobuf是二

14、進(jìn)制的消息,wireshark抓包是無法直接分析的。不過google上面已經(jīng)有了插件。 不過插件只支持UDP.本人在google上面的protobuf-wireshark的基礎(chǔ)上修改了支持TCP的抓包解析,前提是頂層Message只有一個,而且封裝在4個字節(jié)的長度后面。插件下載地址/detail/chenxiaohong3905/(wireshark 1.8.6版本). CSDN沒分?jǐn)?shù)的可以call me,留下你的郵箱。分布式應(yīng)用中基于事件驅(qū)動的應(yīng)用開發(fā)模型本文將為您講述如何為分布式應(yīng)用建立事件驅(qū)動的開發(fā)模型。并以Linux系統(tǒng)為例,展示了事件驅(qū)動

15、開發(fā)的基本框架。1評論:郭洪鋒(ghf_),2001 年 8 月 01 日 內(nèi)容前言從目前看,大量數(shù)據(jù)的流動仍然主要分布在局域網(wǎng)的分布式系統(tǒng)中,該類系統(tǒng)的大流量、實時性的特點(diǎn)要求系統(tǒng)具有實時響應(yīng)、交互動作異步非耦合、高可用性、高可得到性等特征。而因為系統(tǒng)主要局限在局域網(wǎng)內(nèi)運(yùn)行,因而在系統(tǒng)的構(gòu)建上應(yīng)用要具有靈活多樣可靠穩(wěn)定的性能。事實上,良好的局域網(wǎng)應(yīng)用是聯(lián)入廣域網(wǎng)的前提。在該類分布式系統(tǒng)中,引導(dǎo)數(shù)據(jù)流動和分布式動作的往往是事件的作用,或者稱之為消息。事件是激活和驅(qū)動分布式系統(tǒng)的直接原因,也是進(jìn)一步構(gòu)建分布式對象管理的基礎(chǔ)。利用事件驅(qū)動開發(fā)模型,可以快速構(gòu)建分布式系統(tǒng)應(yīng)

16、用,提高分布式應(yīng)用和整個分布式系統(tǒng)的運(yùn)行效率。回頁首事件驅(qū)動的開發(fā)模型首先,在分布式系統(tǒng)中,事件是異步非耦合的,這是系統(tǒng)實時性的要求。因為在分布式系統(tǒng)中,往往各個關(guān)鍵應(yīng)用既是服務(wù)器應(yīng)用,也是客戶應(yīng)用,相互之間從功能上看是對等關(guān)系,如果在同步情況下,一個應(yīng)用驅(qū)動了另一個應(yīng)用的事件,這個應(yīng)用則必須堵塞,以等待事件執(zhí)行的返回狀態(tài),這樣這個應(yīng)用在這段時間內(nèi)則不能處理實時事件。而各個應(yīng)用之間相互不完全依賴的情況也決定了分布式系統(tǒng)中事件的兩端必須為非耦合。事件驅(qū)動的開發(fā)模型包括如下幾個部分: 事件定義庫:該庫定義了應(yīng)用所有認(rèn)知的事件描述,基本信息包括事件標(biāo)識,事件特征,事件處理例程,事件所屬軟件包等。 事

17、件檢測模塊:該模塊負(fù)責(zé)處理事件的收集和分發(fā),當(dāng)接收事件后,分析事件的類型、特征,然后作出相應(yīng)的處理,該模塊是開發(fā)模型的核心。 事件執(zhí)行模塊:負(fù)責(zé)獲知事件入口,解碼事件攜帶數(shù)據(jù),正確執(zhí)行相應(yīng)事件。事件執(zhí)行模塊可以支持事件的持久性,持久性事件的接收方如果中間停止,而在再次啟動后仍可以接收事件。 事件信道:是分布式應(yīng)用之間事件流動的通道。事件信道是單向的,適應(yīng)分布式應(yīng)用的多樣性要求,事件信道存在多種類型,主要有:1)永久可靠的信道。應(yīng)用之間具有頻繁的事件往來或固定的周期性的關(guān)鍵事件要采用這類信道;2)一次性可靠信道。事件的收發(fā)具有偶然性,不經(jīng)常性,但是事件不可丟失;3)廣播數(shù)據(jù)報不可靠信道。信道上的

18、事件是一對多的關(guān)系,可以容忍偶然的數(shù)據(jù)報丟失或失序,如某一些關(guān)鍵應(yīng)用的指示存在的心跳事件可采用該類信道;4)單播數(shù)據(jù)報信道;5)數(shù)據(jù)報可靠信道。這類信道主要適應(yīng)于一對多的可靠事件,該信道在不可靠數(shù)據(jù)報基礎(chǔ)上增加了數(shù)據(jù)報序列號和事件重發(fā)請求,以便形成可靠的事件通道。事件通道為分布式應(yīng)用提高運(yùn)行效率提供了基礎(chǔ)設(shè)施。 事件輸入源:是驅(qū)動事件的源應(yīng)用。包括了事件數(shù)據(jù)的編碼和封裝,編碼是為了使得事件可以在不同的系統(tǒng)平臺上流動,封裝的事件數(shù)據(jù)中,頭部信息固定的為公共可以識別的信息。 最后要提供事件驅(qū)動應(yīng)用API:包括了事件的注冊API,以及實現(xiàn)以上各功能的各類API。API要求簡單明了,為應(yīng)用程序員快速構(gòu)

19、建分布式應(yīng)用提供支持。回頁首Linux系統(tǒng)上事件驅(qū)動的開發(fā)框架目前,Linux操作系統(tǒng)逐漸為人們所接受,在Linux上的分布式系統(tǒng)也逐漸獲得了更廣泛的應(yīng)用。本文在這里描繪了在Linux系統(tǒng)上基于以上事件驅(qū)動模型的簡化開發(fā)框架?;谶@個框架,還可以在Linux上開發(fā)出實用、可靠、穩(wěn)定的事件驅(qū)動軟件包。2.1 事件定義庫事件定義庫記錄了應(yīng)用所關(guān)心的所有事件信息,是事件測試模塊的掃描數(shù)據(jù)區(qū)。定義庫要求查詢方便快速,定義庫可以自由擴(kuò)展。例如可以用以下的結(jié)構(gòu)實現(xiàn): typedef struct / 指向下一個事件信息的指針 void *ptr; / 事件ID int event_id; / 事件屬性,指

20、示事件是否活動等。 int event_propertiy; / 定義事件的數(shù)據(jù)內(nèi)容 struct event_info info; / 事件處理例程,包括了數(shù)據(jù)信息和信道信息 int (int *)(*event_process*)(void *data_buff, void *channel_info); event_table struct event_db / 有效的事件數(shù)量 int event_num; / 事件列表 event_table *event; 2.2 事件檢測模塊事件的檢測是通過對一系列感興趣的文件描述符的檢測來完成的。感興趣的文件描述符包括在文件描述符集內(nèi),一個感興趣

21、的文件描述符對應(yīng)于一類事件。當(dāng)我們檢測到一個文件描述符可讀時,就知道應(yīng)用內(nèi)已經(jīng)驅(qū)動了一個事件。通過掃描事件定義庫可以找到相應(yīng)的事件,然后就可以提交給事件執(zhí)行模塊。可以用如下代碼實現(xiàn)事件檢測模塊: int rts; fd_set fdset; . rts = select(FD_SETSIZE,&fdset,NULL,NULL,NULL,0); if(rts 0 ) if(rts = .) /* 如果檢測到I/O描述符為某一類型的描述符,則*/ . /* 將數(shù)據(jù)提交給事件執(zhí)行模塊 */ else if(rts = .) . 2.3 事件注冊模塊事件要注冊后,應(yīng)用才可以辨識并驅(qū)動該事件。事件的注冊過程實際上是定義事件信息,將信息寫入事件定義庫的過程。2.4 事件信道事件信道不僅定義了事件流動的基礎(chǔ)設(shè)施,也定義了相應(yīng)的事件I/O描述符。例如在一個應(yīng)用內(nèi)部的驅(qū)動事件,事件信道的實現(xiàn)可以采用命名管道,返回的描述符用于檢測內(nèi)部的驅(qū)動事件??梢杂靡韵麓a實現(xiàn): int io_inner mkfifo(fifo_filename,mode) / 創(chuàng)建一個FIFO文件 io_inner = open(fifo_filename, mode); / 獲得該文件描述符應(yīng)用之間的驅(qū)動事件的信道要用到socket描述符。應(yīng)用之間建立了socket鏈路后即建

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論