ProtoBuf, 比起xml和json, 传输的数据里面没有自描述标签, 而且是基于二进制的, 所以有着超高的传输效率, 据牛人张善友的描述, 可以替代WCF的自带的编码方案, 效率有极大的提升.

    在网上搜罗了一遍, 很多博文都是复制张善友的文章, 有些细节没有说清楚, 所以将自己尝试的方法分享给大家.

 

    1. 在VS2013中新建一个 WCF服务库, 名字使用默认的WcfServiceLibrary1

    2. 在当前解决方案再新建一个Console程序, 名字叫Client

    3. 使用nuget安装proto-net, 为什么不用最新的 2.1.0 版本呢? 因为要弹出错误 protobuf-net”已拥有为“NETStandard.Library”定义的依赖项。我估计应该是转.Net Core了, 没有继续研究了, 先用 2.0.0.668 吧

Install-Package protobuf-net -Version 2.0.0.668 -ProjectName WcfServiceLibrary1

Install-Package protobuf-net -Version 2.0.0.668 -ProjectName Client

    将WcfServiceLibrary1\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll拷贝到

\WcfServiceLibrary1\WcfServiceLibrary1

WcfServiceLibrary1\Client

    4. 在服务端注册 行为扩展: 将下面的代码拷贝到<system.serviceModel>下面, 注册行为扩展的时候要求protobuf-net.dll就放在项目文件夹, 这就是第3步拷贝的原因

    <extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67" />
</behaviorExtensions>
</extensions>

    5. 在服务端将 行为扩展 应用在 终结点行为 上: 在<behaviors>下面拷贝

      <endpointBehaviors>
<behavior name="protoEndpointBehavior">
<protobuf/>
</behavior>
</endpointBehaviors>

    6. 还有就是让服务使用这个终结点行为, 在 <endpoint> 下添加

behaviorConfiguration="protoEndpointBehavior"

    App.config最终样子

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67" />
</behaviorExtensions>
</extensions>
<services>
<service name="WcfServiceLibrary1.Service1">
<endpoint address="" behaviorConfiguration="protoEndpointBehavior"
binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="protoEndpointBehavior">
<protobuf/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

    7. 配置文件写好了后, 还需要修改IServer.cs, 这里只是简单例子, 就将 CompositeType 作为例子, 需要添加ProtoContract、ProtoMember 两种特性, 这样protobuf-net的编码器才能正确识别

    [DataContract]
[ProtoContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello "; [DataMember]
[ProtoMember(1)] public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
} [DataMember]
[ProtoMember(2)]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
   8. public interface IService1 还要要添加 [ServiceContract] 特性

    

    9. 客户端引用WCF服务, 因为WCF服务就在本项目, 所以要选择 解决方案中的服务, 就命名为ServiceReference1吧

   10. 客户端也要增加刚才的扩展和终结点行为, 这样客户端才能解析protobuf数据, 最终App.config 是这样的

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67" />
</behaviorExtensions>
</extensions>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/"
behaviorConfiguration="protoEndpointBehavior" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="protoEndpointBehavior">
<protobuf />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

    11. 将解决方案设置为双启动, 右键解决方案 -->  属性 --> 启动项目 --> 多启动项目    

     11. 好了, 可以在客户端调用服务了

static void Main(string[] args)
{
var proxy =new ServiceReference1.Service1Client();
var result=proxy.GetDataUsingDataContract(new ServiceReference1.CompositeType(){ StringValue="test });
Console.WriteLine(result.StringValue);
}

但是得到结果是null

    12. 查看别人的博文 在Wcf中应用ProtoBuf替代默认的序列化器  , 原来protobuf 不是WCF的嫡出, 通过服务引用, 并不会像DataMember这种原生支持的Attribute那样, 把ProtoMember传输到Client的自动生成代码里, 所以还需要手工添加, 蛋疼啊

    在打开的Reference.cs中找到属性 public bool BoolValue   添加  [ProtoMember(1)]

    找到属性 public string StringValue 添加  [ProtoMember(2)]

     这下终于有结果了

 

 

 

     后记, protobuf 并不是为WCF准备的, 而是应该与 gRPC 配合使用, 在 gRPC 的示例文档中可以看到如将一个非常简单的 .proto文件编译成复杂的cs文件, 然后分别被服务端和客户端引用, 最终实现远程调用, 不过示例环境是VS2015

 

源代码

WCF use ProtoBuf的更多相关文章

  1. 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC

    Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC  的定义语法,但是一直以来,Google 只开 ...

  2. 基于HTTP/2和protobuf的RPC框架:GRPC

    谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobu ...

  3. .NET开源Protobuf-net组件葵花手册

    一.前言 我们都知道 protobuf是由Google开发的一款与平台无关,语言无关,可扩展的序列化结构数据格式,可用做数据存储格式, 通信协议 ! 在前面<.NET开源Protobuf-net ...

  4. .NET 开源Protobuf-net从入门到精通

    <.NET 开源Protobuf-net从入门到精通>课程包含以下两个部分: 一..NET 开源Protobuf-net组件[数据存储篇] 本次分享课程包含以下干货知识点: 1.什么是Pr ...

  5. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  6. WCF服务上应用protobuf

    WCF服务上应用protobuf Web api  主要功能: 支持基于Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, updat ...

  7. WCF服务上应用protobuf z

    protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样 的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多.虽然是二进制数据格式,但并没有因此变得 ...

  8. WCF与Web API 的应用场景

    Web api  主要功能: 支持基于Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, update, delete)操作 请求的回 ...

  9. Unity3D客户端和Java服务端使用Protobuf

    转自:http://blog.csdn.net/kakashi8841/article/details/17334493 前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖 ...

随机推荐

  1. 【AppCan 开发者】北京开发者交流会之行

    不久前AppCan官方组织了开发者交流会活动,我有幸参加了这次活动,官方报销全部费用,还有妹子相伴,哇哇,这是光明正大打FB的节奏啊~ (呃,说实话,这是俺第一次去帝都~心里挺激动的~) 10.25帝 ...

  2. 《JavaScript高级程序设计》学习笔记(2)--JS运算符详解

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 思维导图 前面对JS的运算符的操作很多细节的东西没有提及,今天给大家分享一张网上找的思维导图,对这一部 ...

  3. 使用es6的set和map实现数组去重复

    var set = new Set();var arr = [1, 2, 3, 3, 2, 1];arr.map(val => set.add(val));// arr.map(function ...

  4. NK3C:异常处理(前端)

    前端的提示有些也不是很规范,主要体现如下: 1.ResultInfo的返回值,false的情况下,未做处理: 2.ResultInfo的返回值,false的情况下,做了其他操作,未提示错误:(虽然没报 ...

  5. Google黑板报: 数学之美系列(网上找的原链接)

    转载地址:http://blog.sina.com.cn/s/blog_47cccb02010009u0.html 系列一 -- 统计语言模型 http://googlechinablog.com/2 ...

  6. 修改tomcat应用日志默认编码格式

    前言 今天开发跟我说tomcat日志中的中文不能正常显示,根据以往的经验,我觉得可能跟服务器的编码有关,于是尝试各种方法,但还是没能解决问题. 后来我突然想到会不会跟tomcat的设置有关呢,于是在网 ...

  7. spark优化

    spark.shuffle.consolidateFiles=false 默认是false,shuffle阶段不进行文件的合并,1000个map和1000个reduce将产生1000 000个文件. ...

  8. Git版本控制与工作流

    基本概念 Git是什么? Git是分布式版本控制系统,与SVN类似的集中化版本控制系统相比,集中化版本控制系统虽然能够令多个团队成员一起协作开发,但有时如果中央服务器宕机的话,谁也无法在宕机期间提交更 ...

  9. 史航416第八次作业&总结

    一.知识点总结: 1.数组的输入,输出及对整个数组所有元素进行操作通常都用循环结构实现. 2.可以只给部分元素赋初值.当{ }中值的个数少于元素个数时,只给前面部分元素赋值. 3.只能给元素逐个赋值, ...

  10. maven配置之setting配置

    <!--声明语句--> <?xml version="1.0" encoding="UTF-8"?> <settings xmln ...