我正在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>
答案 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();
}
}
}
这应该让你非常接近问题所在。