4

我们有一个从 C# 控制台应用程序运行的“工作者”服务,对于开发,我们总是运行该服务的单个实例,它获取数据块并执行一些计算,这些数据块由另一个服务提供(跟踪剩下多少数据等)

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

TransportManager 未能使用 NetTcpPortSharing 服务侦听提供的 URI:该 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> 

申请代码:

var host = new ServiceHost(typeof(WorkerService));
host.Open();

我们如何为每个实例提供不同的 URI,以便至少端口保持不变?

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

4

3 回答 3

4

如果您想要拥有多个服务实例,拥有单个服务主机就足够了 - 只需使用ServiceBehaviorAttribute装饰您的 WorkerService

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Percall)] 
public class WorkerService : IWorkerService 
{
  //...service data
}

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

但是,如果您希望拥有多个服务主机,那么不可能有两个服务主机在完全相同的 url 上托管相同的服务。

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

<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>

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

net.tcp://localhost:8001/WorkerAssignment

net.tcp://localhost:8001/QAWorkerAssignment

于 2012-09-13T19:08:16.540 回答
1

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>
于 2012-09-22T01:02:03.913 回答
0

你可以定义你的specific behavior

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall, 
                 ConcurrencyMode = ConcurrencyMode.Multiple)]
于 2012-09-13T19:02:56.720 回答