首页 > 代码库 > WCF use ProtoBuf

WCF use ProtoBuf

    ProtoBuf有着超高的传输效率, 可以替代WCF的xml和二进制编码, 可以试一试

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

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

    使用nuget安装proto-net, 为什么不用最新的 2.1.0 版本呢? 因为要弹出错误 protobuf-net”已拥有为“NETStandard.Library”定义的依赖项。

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

    注册 行为扩展: 将下面的代码拷贝到<system.serviceModel>下面

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

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

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

    还有就是让服务使用这个终结点行为, 在 <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=http://www.mamicode.com/"localhost" />>

    配置文件写好了后, 还需要修改IServer.cs, 这里只是介绍, 只将 CompositeType 作为例子, 需要添加ProtoContract、ProtoMember 两种特性

    [DataContract]    [ProtoContract]    public class CompositeType    {        bool boolValue = http://www.mamicode.com/true;>
    public interface IService1 也要添加 [ServiceContract] 特性

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

技术分享

   客户端也要增加刚才的扩展和终结点行为, 最终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>

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

static void Main(string[] args){    var proxy =new ServiceReference1.Service1Client();    var result=proxy.GetDataUsingDataContract(new ServiceReference1.CompositeType(){ StringValue=http://www.mamicode.com/"test });>

可得到结果是null

技术分享

查看别人的博文, 原来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