views:

41

answers:

0

I've been playing around with WCF peer to peer, one way operation contract and callbacks. I have a following service:

[ServiceContract(CallbackContract = typeof(ICodeFoundCallback))]
public interface ICodeSearch
{
    [OperationContract(IsOneWay = true)]
    void Search(string searchQuery);
}


public interface ICodeFoundCallback
{
    [OperationContract(IsOneWay = true)]
    void Found(string found);
}


public class CodeSearchService : ServiceWithCallback<ICodeFoundCallback>, ICodeSearch
{
    public void Search(string searchQuery)
    {
        Console.WriteLine("Searching for :" + searchQuery);
        Callback(t=> t.Found(searchQuery));
    }
}

public class ServiceWithCallback<T>
{
    protected void Callback(Action<T> call)
    {
        var callbackChanel = OperationContext.Current.GetCallbackChannel<T>();
        call(callbackChanel);
    }
}

with such config on server

<system.serviceModel>
    <services>
      <service name="CodeSearch.Service.CodeSearchService" behaviorConfiguration="CodeSearchServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.p2p://CodeSearchService"/>
          </baseAddresses>
        </host>

        <endpoint
            name="CodeSearchServiceEndpoint"
            address=""
            binding="netPeerTcpBinding"
            bindingConfiguration="BindingUnsecure"
            contract="CodeSearch.Service.ICodeSearch"
        />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CodeSearchServiceBehavior">
          <serviceMetadata />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netPeerTcpBinding>
        <binding  name="BindingUnsecure">
          <security mode="None"/>
          <resolver mode="Pnrp"/>
        </binding>
      </netPeerTcpBinding>
      <customBinding>
        <binding name="CodeSearchServiceEndpoint">
          <binaryMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
              maxSessionSize="2048">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          </binaryMessageEncoding>
          <peerTransport maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
              port="0">
            <security mode="None" />
          </peerTransport>
        </binding>
      </customBinding>
    </bindings>
<system.serviceModel>

And simple client generated by Visual studio tooling.

When I run two or more servers, and client invokes Search method:

  • search method is called on each server
  • first server calls client callback properly
  • second server throws ArgumentException "A property with the name 'TransactionFlowProperty' already exists" when invoking client callback (Found method)

I've no idea what is going on since as far as I know transaction flow is by default set to none.

Could anyone help me solve this issue ?