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 ?