C# 自托管WCF服务的多个实例

C# 自托管WCF服务的多个实例,c#,.net,wcf,multiple-instances,self-hosting,C#,.net,Wcf,Multiple Instances,Self Hosting,我们在c#中的控制台应用程序中运行了一个“worker”服务,在开发过程中,我们总是运行该服务的一个实例,它获取数据块并执行一些计算,这些数据块由另一个服务提供(它跟踪剩下的数据量等) 现在在QA中,我们希望同时(在同一台机器上)运行“worker”服务的多个实例。但是,一旦启动第二个实例,我们就会得到一个异常: TransportManager无法使用侦听器侦听提供的URI NetCpPortShared服务:URI已注册到 服务 我们正在使用netTcpBinding,端点地址被硬编码到ap

我们在c#中的控制台应用程序中运行了一个“worker”服务,在开发过程中,我们总是运行该服务的一个实例,它获取数据块并执行一些计算,这些数据块由另一个服务提供(它跟踪剩下的数据量等)

现在在QA中,我们希望同时(在同一台机器上)运行“worker”服务的多个实例。但是,一旦启动第二个实例,我们就会得到一个异常:

TransportManager无法使用侦听器侦听提供的URI NetCpPortShared服务:URI已注册到 服务

我们正在使用netTcpBinding,端点地址被硬编码到app.config中,并且保持不变,因此我假设我们得到了这个错误

<services>
    <service behaviorConfiguration="CoreBehavior" name="WorkerService">
        <endpoint address="net.tcp://localhost:8001/WorkerAssignment" binding="netTcpBinding" contract="IWorkerService" bindingConfiguration="CoreTcpBinding"/>
    </service>
</services>
<bindings>
    <netTcpBinding>
        <binding name="CoreTcpBinding" portSharingEnabled="true">
            <security mode="None"/>
        </binding>
    </netTcpBinding>
</bindings> 
我们如何为每个实例提供不同的URI,以便至少端口保持不变


或者如果有不同的方式运行同一服务的多个实例?

您可以定义您的
特定行为

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall, 
                 ConcurrencyMode = ConcurrencyMode.Multiple)]

如果您想拥有多个服务实例,而仅仅拥有一个服务主机就足够了,只需使用ServiceBehaviorAttribute装饰WorkerService即可

这将确保对服务的每次调用都将首先创建服务的新实例。可以找到创建服务类的其他方法

但是,如果您希望有多个服务主机,则不可能有两个服务主机在完全相同的url上承载相同的服务

另一种情况是,如果希望一个服务主机在具有相同基址和自定义uri的多个端点上承载相同的服务。在这种情况下,您可以使用重载的ServiceHost构造函数或调查方法AddBaseAddress、AddServiceEndpoint。或者,如果您想从配置文件中执行此操作,那么下面是一个简单的示例,代码稍微修改一下

<service behaviorConfiguration="CoreBehavior" name="WorkerService">
    <endpoint address="WorkerAssignment" binding="netTcpBinding" contract="IWorkerService"/>
    <endpoint address="QAWorkerAssignment" binding="netTcpBinding" contract="IWorkerService"/>
  <host>
    <baseAddresses>
      <add baseAddress="net.tcp://localhost:8001/" />
    </baseAddresses>
  </host>
</service>

使用此配置,您的服务将有两个端点

净。tcp://localhost:8001/WorkerAssignment

净。tcp://localhost:8001/QAWorkerAssignment


Murtaza您是对的,您仍然需要多个实例,问题是如何提供不同的端口

备选方案1: 对于每个服务实例:在调用ServiceHost.Open之前,您可以向服务添加端点

ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService))
WSHttpBinding binding = new WSHttpBinding();
serviceHost.AddServiceEndpoint(typeof(ICalculator), binding, "http://localhost:8000/servicemodelsamples/service/basic");
在上面的代码中,地址部分可以为服务的每个实例具有不同的端口

详情如下

备选方案2:启用端口共享

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding portSharingEnabled="true">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>


我的服务已被修饰为:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]公共类分配服务:IWorkerService
我得到异常:
IP端点0.0.0:8001上已经有一个侦听器。确保您没有在应用程序中多次尝试使用此端点,并且没有其他应用程序侦听此端点。
我试图实现的是让Worker服务运行两次,我认为拥有两个不同的端点地址并不能解决问题?当您在同一地址上启动多个服务主机时,会出现这种异常,这是意料之中的。在这种情况下,一台主机中的不同端点可以解决此问题。但是,如果您只启动一台主机,那么您可以使用控制台中的以下命令检查,例如
netstat-aon
如果此端口上已经有另一个应用程序,为什么要运行同一服务的多个实例,这是性能需要吗?是,主服务“分配”工作(在内部划分工作并跟踪下一批工作),工人服务实际执行工作。因此,多个辅助服务将减少我们的工作时间。为了满足您分配和分配工作的需要,您可以使用中间路由服务(多一个链接)查看WCF中的负载平衡。好的,分配部分不是这里的问题,即使我使用路由机制,我仍然需要多个实例(辅助服务)打开以路由到,这意味着打开多个端口。
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService))
WSHttpBinding binding = new WSHttpBinding();
serviceHost.AddServiceEndpoint(typeof(ICalculator), binding, "http://localhost:8000/servicemodelsamples/service/basic");
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding portSharingEnabled="true">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>