I've set up a basic Service Fabric solution with a stateless service and Web API and tested that everything works using the default service remoting listener. Happy days!
When I try to replace the default listener with a service bus relay (how I intend to communicate with the service) I'm getting errors at startup.
CreateServiceInstanceListeners()
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(context => {
var wcfRelay = new WcfCommunicationListener<ICommercial>(
wcfServiceObject: this,
serviceContext: context,
endpointResourceName: "serviceRelay");
return wcfRelay;
})
};
}
Service config (app.config)
<system.serviceModel>
<extensions>…</extensions>
<services>
<service name="Commercial.Service.CommercialService">
<endpoint address="http://[namespace].servicebus.windows.net/CommercialService"
name="serviceRelay"
binding="basicHttpRelayBinding"
contract="Commercial.Interface.ICommercial"
behaviorConfiguration="relayToken" />
</service>
</services>
<bindings>
<basicHttpRelayBinding>
<binding closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" maxBufferSize="5886800" maxBufferPoolSize="524288" maxReceivedMessageSize="5886800" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="5886800" maxArrayLength="5886800" maxBytesPerRead="5886800" maxNameTableCharCount="16384" />
</binding>
</basicHttpRelayBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="relayToken">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedAccessSignature keyName="RootManageSharedAccessKey" key="[key]" />
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
If I break in the listener creation I see it's creating two service endpoints:
And eventually I get this error showing up for each node in Service Fabric Explorer.
Unhealthy event: SourceId='System.RA', Property='ReplicaOpenStatus', HealthState='Warning', ConsiderWarningAsError=false. Replica had multiple failures in_Node_1 API call: IStatelessServiceInstance.Open(); Error = System.InvalidOperationException (-2146233079) The Service contains multiple ServiceEndpoints with different ContractDescriptions which each have Name='ICommercial' and Namespace='http://[schema_path]/20170713'. Either provide ContractDescriptions with unique Name and Namespaces, or ensure the ServiceEndpoints have the same ContractDescription instance. at System.ServiceModel.Dispatcher.UniqueContractNameValidationBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase) at System.ServiceModel.Description.DispatcherBuilder.ValidateDescription(ServiceDescription description, ServiceHostBase serviceHost) at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) at System.ServiceModel.ServiceHostBase.InitializeRuntime() at System.ServiceModel.ServiceHostBase.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state) at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen() at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state) at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state) at Microsoft.ServiceFabric.Services.Communication.Wcf.Runtime.WcfCommunicationListener`1.Microsoft.ServiceFabric.Services.Communication.Runtime.ICommunicationListener.OpenAsync(CancellationToken cancellationToken) at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ServiceFabric.Services.Runtime.StatelessServiceInstanceAdapter.d__14.MoveNext()
I'm not exactly clear how to remedy this "Either provide ContractDescriptions with unique Name and Namespaces, or ensure the ServiceEndpoints have the same ContractDescription instance".