WCF服務上應用protobuf
protobuf是google提供的一個開源序列化框架,類似于XML,JSON這樣的數據表示語言,其最大的特點是基于二進制,因此比傳統的XML表示高效短小得多。雖然是二進制數據格式,但并沒有因此變得復雜,開發人員通過按照一定的語法定義結構化的消息格式,然后送給命令行工具,工具將自動生成相關的類,可以支持java、c++、python等語言環境。通過將這些類包含在項目中,可以很輕松的調用相關方法來完成業務消息的序列化與反序列化工作。
protobuf在google中是一個比較核心的基礎庫,作為分布式運算涉及到大量的不同業務消息的傳遞,如何高效簡潔的表示、操作這些業務消息在google這樣的大規模應用中是至關重要的。而protobuf這樣的庫正好是在效率、數據大小、易用性之間取得了很好的平衡。
更多信息可參考官方文檔
protobuf這樣的庫是很方便高效的,那么自然的想到在網絡編程中用來做業務消息的序列化、反序列化支持。在基于UDP協議的網絡應用中,由于UDP本身是有邊界,那么用protobuf來處理業務消息就很方便。但在TCP應用中,由于TCP協議沒有消息邊界,這就需要有一種機制來確定業務消息邊界。在TCP網絡編程中這是必須面對的問題。在tcp網絡編程中,要反序列化業務消息,就要先知道業務數據的大小。而且在實際應用中可能在一個發送操作中,發送多個業務消息,而且每個業務消息的大小、類型都不一樣。而且可能發送很大的數據流,比如文件。顯然消息邊界的確認問題和protobuf庫無關,還得自己搞定。在官方文檔中也提到,protobuf并不太適合來作大數據的處理,當業務消息超過1M時,就應該考慮是否應該用另外的替代方案。當然對于大數據,你也可以分割為多個小塊用protobuf做小塊消息封裝進行傳遞。但對很多應用這樣的作法顯得比較多余,比如發送一個大的文件,一般是在接收方從協議棧收到多少數據就寫多少數據到磁盤,這是一種邊接收邊處理的流模式,這種模式基本上和每次收到的數據量沒有關系。這種模式下再采用分割成小消息進行反序列化就顯得多此一舉了。
借助于WCF這樣的網絡編程框架,然后結合protobuf這樣的序列化框架,網絡編程中技術基礎設施層面的東西就給我們解決得差不多了,我們可以真正只關注于業務的實現。
protobuf的dotNet實現protobuf-net, 支持WCF的DataContact,WCF程序幾乎不需要什么修改就能使用。
一個最小的可以工作的例子就是protobuf-net提供的(client, server),它使用的是共享契約的方式,通過WCF的配置方式,添加一個Endpoint-behavior,引用一個自定義的WCF擴展。
<behaviors>
<endpointBehaviors>
<behavior name="protoEndpointBehavior">
<protobuf/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.280, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
在客戶端和服務端都加上這個behavior,例如下面的例子
客戶端:
<client>
<endpoint address="http://localhost:33545/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1" behaviorConfiguration="protoEndpointBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
服務端:
<endpoint address="" binding="wsHttpBinding" contract="TestWcfDto.IService1" behaviorConfiguration="protoEndpointBehavior">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</service>
注意事項:
1、類繼承層次只支持1層
2、類似于WCF的KnownType,Protobuf使用ProtoInclude http://stackoverflow.com/questions/6541718/protobuf-net-wcf-multiple-nested-generic-abstract-objects-serialization-v282
3、How to add dynamically a list of known type to a Protobuf-net formatter?
參考文章:
.net自帶二進制序列化,XML序列化和ProtoBuf序列化的壓縮對比
http://www.rzrgm.cn/onlytiancai/archive/2009/07/02/protobuf_net_test.html
Windows Communication Protocols (MCPP) http://msdn.microsoft.com/en-us/library/cc216513(PROT.10).aspx
Silverlight Binary Serialization using Protobuf-net
http://www.codeproject.com/KB/silverlight/silverlight-protobufnet.aspx
http://marcgravell.blogspot.com/search/label/protobuf-net
http://blogs.msdn.com/b/dmetzgar/archive/2011/03/29/protocol-buffers-and-wcf.aspx
http://www.drdobbs.com/windows/working-with-protobuf-wcf-services/240159282?pgno=1
歡迎大家掃描下面二維碼成為我的客戶,扶你上云

浙公網安備 33010602011771號