多个实例从一台物理机器到不同的WCF服务

时间:2014-07-10 09:21:08

标签: c# wcf

我正在IIS上运行WCF服务。客户端通过net.tcp连接。在一台物理机器打开客户端应用程序的两个实例之前,一切正常。然后,只从服务中提供第二个应用程序。

我认为这是一个端口问题,一台机器打开与srvAddress:port / service.svc的连接,服务器不知道它必须响应哪个客户端实例。

我的第一个问题:如果我在client1(pc1)上打开ip:port / service.svc,WCF会使用哪个本地客户端端口来响应?如果我然后在client2(仍然是pc1)上打开ip:port / service.svc,为什么WCF没有正确处理?

服务器

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerSession)]
public class WCFService : IWCFService
{
    public State OpenSession(string clientKey)
    {
        Callback = OperationContext.Current.GetCallbackChannel<IWCFServiceCallback>();            
    }
}

客户端:

var callback = new WCFServiceCallback();
var instanceContext = new InstanceContext(callback);
Server = new WCFServiceClient(instanceContext);
Server.OpenSession("secret");

WCF配置服务器

<?xml version="1.0"?>
<configuration>
  <system.web>
    <customErrors mode="Off"/>
    <compilation/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <!-- Add the following element to your service behavior configuration. -->
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <!--Hosting in a IIS: -->
      <service name="WCFServiceLibrary.Service.WCFService">
        <endpoint address="net.tcp://myservice.com:808/Service.svc" binding="netTcpBinding" bindingConfiguration="InsecureTcp" contract="WCFServiceLibrary.Contract.IWCFService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://myservice.com/Service/"/>
          </baseAddresses>
        </host>
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="InsecureTcp" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
          <security mode="None" />
          <readerQuotas maxDepth="2000000" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
</configuration>

WCF配置客户端

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
    </sectionGroup>
  </configSections>

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IWCFService">
          <security mode="None"/>
        </binding>
      </netTcpBinding>
    </bindings>

    <client>
      <endpoint address="net.tcp://myservice.com/Service.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IWCFService" contract="ServiceReference.IWCFService" name="NetTcpBinding_IWCFService"/>
    </client>
  </system.serviceModel>

  <userSettings />

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
  </startup>

</configuration>

1 个答案:

答案 0 :(得分:0)

我不确定这是错的;但是,我怀疑这些步骤将帮助您调试它。

您的WCF应具有类库的输出类型。在同一解决方案中创建另一个项目,并添加WCF服务作为对新项目的引用。

接下来,从控制台手动打开WCF服务。您可以使用类似于以下内容的代码执行此操作。

        //Alternatively you can use :
        //ServiceHost host = new ServiceHost(typeof(ApiTestService), new Uri(PipeService));
        Api api = new ApiTestService();
        ServiceHost host = new ServiceHost(api,new Uri(PipeService));

        //Add all your bindings.
        host.AddServiceEndpoint(typeof(IApiService), new NetNamedPipeBinding(), ApiPipeServiceName);

        host.BeginOpen(OnOpen, host);
        Console.ReadLine();
        host.BeginClose(OnClose, host);

其中OnOpen和OnClose如下所示。

    void OnOpen(IAsyncResult ar)
    {
        ServiceHost service = (ServiceHost)ar.AsyncState;
        service.EndOpen(ar);
    }
    void OnClose(IAsyncResult ar)
    {
        ServiceHost service = (ServiceHost)ar.AsyncState;
        service.EndClose(ar);
    }

然后再次尝试导入服务引用并比较配置文件。如果您注意到这两个请求都是服务,则意味着WCF配置可能出现问题。如果您仍然发现无法为第二个请求提供服务,则可能意味着您应该尝试手动访问您的服务:

您可以通过为您的服务创建代理来实现此目的。

这将是代理类的示例:

public class MyPipeClient : IMyService, IDisposable
{   
    //Sub IMyService with your service interface contract
    ChannelFactory<IMyService> myServiceFactory;

    public MyPipeClient()
    {
        // Sub NetNamedPipeBinding with your bindings.
        myServiceFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName) );


    }

    //Implementation Details no one cares about would go here
    //...
    //Example where Hello is one of the functions from my Service.
    public String Hello(String Name)
    {
        return Channel.Hello(Name);
    }


    public IMyService Channel
    {
        get
        {
            return myServiceFactory.CreateChannel();
        }
    }
}

这应该让你非常接近问题所在。

相关问题