带有 Protobuf-net 的端点行为配置 WCF

Posted

技术标签:

【中文标题】带有 Protobuf-net 的端点行为配置 WCF【英文标题】:Endpoint behavior configuration WCF with Protobuf-net 【发布时间】:2011-08-12 06:10:12 【问题描述】:

我有一个 WCF 服务 (.NET 4),它公开了 4 个端点,其中一个端点配置了 protobuf-net (V1.0.0.280) 行为扩展。但是,我注意到 ALL 定义的端点(包括未配置 protobuf-net 的端点)会启动 protobuf-net 行为!我在下面粘贴了我的配置。我错过了什么吗?非常感谢任何帮助.. thx

    <service name="MyService" behaviorConfiguration="MyServiceBehavior">
    <endpoint address="Http.Basic" binding="basicHttpBinding" bindingConfiguration="Http.Basic.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
    <endpoint address="Http.Binary" binding="customBinding" bindingConfiguration="Http.Binary.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
    <endpoint address="Tcp.Binary" binding="customBinding" bindingConfiguration="Tcp.Binary.Config" contract="IMyService" behaviorConfiguration="DefaultBehavior" />
    <endpoint address="Http.ProtoBuf" binding="basicHttpBinding" bindingConfiguration="Http.Basic.Config" contract="IMyService" behaviorConfiguration="ProtoBufBehavior" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8085/MyService"/>
        <add baseAddress="net.tcp://localhost:8086/MyService"/>
      </baseAddresses>
    </host>
  </service>

  <behaviors>
    <serviceBehaviors>
      <behavior name="MyServiceBehavior">
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="DefaultBehavior">
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
      <behavior name="ProtoBufBehavior">
        <ProtoBufSerialization />
      </behavior>
    </endpointBehaviors>
  </behaviors>

  <bindings>
    <basicHttpBinding>
      <binding name="Http.Basic.Config" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
      </binding>
    </basicHttpBinding>
    <customBinding>
      <binding name="Http.Binary.Config" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
        <binaryMessageEncoding />
        <httpTransport allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" />
      </binding>
      <binding name="Tcp.Binary.Config" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
        <binaryMessageEncoding />
        <tcpTransport hostNameComparisonMode="StrongWildcard" />
      </binding>
    </customBinding>
  </bindings>

【问题讨论】:

我们在以编程方式添加的 proto-behaviour 中遇到了同样的问题 【参考方案1】:

这很奇怪,但是(检查代码)我只应用更改 WCF 提供给我的端点:

    void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    
        ReplaceDataContractSerializerOperationBehavior(endpoint);
    

    void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    
        ReplaceDataContractSerializerOperationBehavior(endpoint);
    

    private static void ReplaceDataContractSerializerOperationBehavior(ServiceEndpoint serviceEndpoint)
    
        foreach (OperationDescription operationDescription in serviceEndpoint.Contract.Operations)
        
            ReplaceDataContractSerializerOperationBehavior(operationDescription);
        
    


    private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
    
        DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        if (dcsOperationBehavior != null)
        
            description.Behaviors.Remove(dcsOperationBehavior);
            description.Behaviors.Add(new ProtoOperationBehavior(description));
        
    

即“给定一个端点(通过 WCF),循环遍历该端点中的每个操作(方法),并将序列化程序从 DCS 更改为 PB”

这提出了一个有趣的可能性,即合约定义(以及操作定义)本身在所有端点之间共享 - 但老实说我不确定这一点。如果 的情况,我认为每个端点都不可能有不同的处理器。但是,我不是 WCF 专家。这……令人困惑。

【讨论】:

非常感谢您的超快速响应,我明白您的意思。我在玩这个的时候注意到了一些非常奇怪的事情,也就是说,如果我将具有 protobuf 行为的端点作为配置中的最后一个节点,那么一切都按预期工作。但是,如果我将它移动到第一个位置,那么所有端点都会拿起protobuf。如果我将它移到两者之间,那么在它拾取 protobuf 之后定义的端点!如果我找到根本原因,将深入挖掘并发布 据我了解,contractDescription 确实在端点之间共享。但我不明白为什么 proto-behaviour 仅添加到端点之后定义的端点,带有 proto-behaviuor(包括显式配置行为的端点)。我们使用与@Japps 类似的解决方案:将端点与 proto 作为最后一个端点添加到主机

以上是关于带有 Protobuf-net 的端点行为配置 WCF的主要内容,如果未能解决你的问题,请参考以下文章

意外的 protobuf-net 序列化程序行为

使用带有标志枚举的 ProtoBuf-Net 时出错

带有未知子类的 Protobuf-net 异常

带有 ServiceStack 和紧凑框架的 Protobuf-net

带有枚举的 Protobuf-net 反序列化异常

使用带有 protobuf-net 异常的代理对 List<T> 进行序列化