Basic Idea - I have a stateless service that implements an Owin communication Listener over http to service WebApi based public clients. I want to add a second listener that will receive requests within the cluster over Rpc using the built in ServiceRemotingListener(). The reason is that I don't want this listener to be public as it implements a non-public management interface for the stateless service. Here is the setup...:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(initParams => new OwinCommunicationListener("MyWebService", new Startup(_options, this), initParams),"MyServiceHttp"),
new ServiceInstanceListener(initParams => new ServiceRemotingListener<Interfaces.IConfig>(initParams, this),"MyServiceRpc")
};
}
When I add the second listener, I get an exception starting the app...
this.serverHandle = WebApp.Start(this.listeningAddress, appBuilder => this.startup.Configuration(appBuilder));
Exception thrown: 'System.Net.Sockets.SocketException' in System.dll Exception thrown: 'System.ServiceModel.CommunicationException' in System.ServiceModel.dll Exception thrown: 'System.ServiceModel.CommunicationException' in System.ServiceModel.dll Exception thrown: 'System.ServiceModel.CommunicationException' in System.ServiceModel.Internals.dll --multiple repeats--- Exception thrown: 'System.ServiceModel.CommunicationException' in System.Fabric.dll
(not sure how to get the exception details. My "try {} " surrounding did not trap an exception.)
Once in this state, I get subsequent exceptions as the service attempts to auto-restart - the errors are about port sharing.
Anything I can do to make WebApi communication listeners work alongside ServiceRemotingListener? I am assuming at this point that under the hood, ServiceRemotingListener is using http as well and they don't play nicely together.
ok, the solution turned out to be straight forward but not obvious. The docs seem to encourage port sharing approach even though the TCP/RPC and HTTP don't play together.
Basically, I added a second endpoint to the service manifest even though the docs say that each service can only listen on one port.
I left the default / first endpoint for the ServiceRemotingListener to register and added a second that listened specifically to port 8083.
<Endpoint Name="ServiceEndpoint" Protocol="http" Type ="Input"/>
<Endpoint Name="ServiceEndpoint2" Protocol="http" Port="8083" Type ="Input"/>
Then in the IOwinCommunicationsListener, I specified the second endpoint which picked up the alternative port number (I assumed the ServiceInstanceListener would use the default/first end point).
var codePackageActivationContext = this.serviceInitializationParameters.CodePackageActivationContext;
var port = codePackageActivationContext.GetEndpoint("ServiceEndpoint2").Port;
The CreateServiceInstanceListeners were left without any extra config. As above, I wonder if I could use the ServiceRemoteListenerSettings to force the ServiceRemotinglistener to use the alternative port instead of the IOwinCommunicationsListener above)
return new[]
{
new ServiceInstanceListener(initParams => new ServiceRemotingListener<Interfaces.IConfig>(initParams, this),"MyRpc"),
new ServiceInstanceListener(initParams => new OwinCommunicationListener("ShopifyWebService", new Startup(_options, this), initParams),"MyOwin")
};
Hope this helps save someone else a lot of time.
来源:https://stackoverflow.com/questions/34836150/service-fabric-multiple-communication-listeners