C#WCF NetTcpBinding超时无法正常工作

时间:2016-03-10 12:49:19

标签: c# wcf tcp nettcpbinding

我在初始通话时遇到NetTcpBinding的开启,发送,回复和关闭超时问题([OperationContract(IsOneWay = true, IsInitiating = true)]) 目前我正在尝试连接到给定的IPAddress,如果失败,我将连接到不同的地址。 这是因为我无法通过我的外部IP连接到我自己的服务器(由于我的路由器上的NAT环回?),而不是有两个版本(一个用于公共,一个用于我自己)我使用Try-Catch系统尝试连接到我的外部IP,如果它工作 - >继续,如果失败 - >尝试本地IP - >继续。

问题是超时值。由于我正在等待抛出和捕获异常,我需要尽可能地降低此值(首选5秒)而不是默认值~20秒。

我尝试在客户端和服务器端设置这些值

tcpBinding.OpenTimeout = new TimeSpan(0, 0, 5);
tcpBinding.CloseTimeout = new TimeSpan(0, 0, 5);
tcpBinding.SendTimeout = new TimeSpan(0, 0, 5);
tcpBinding.ReceiveTimeout = new TimeSpan(0, 0, 5);

服务器端设置:

svh = new ServiceHost(typeof(ServiceAssembly.ServiceImplementation));
NetTcpBinding tcpBinding = new NetTcpBinding();

tcpBinding.MaxConnections = 100;
tcpBinding.MaxBufferPoolSize = (int)4096000;
tcpBinding.MaxBufferSize = 4096000;
tcpBinding.MaxReceivedMessageSize = (int)4096000;
tcpBinding.OpenTimeout = new TimeSpan(0, 0, 5);
tcpBinding.CloseTimeout = new TimeSpan(0, 0, 5);
tcpBinding.ReceiveTimeout = new TimeSpan(0, 0, 5);
tcpBinding.SendTimeout = new TimeSpan(0, 0, 5);
tcpBinding.ReliableSession.Ordered = true;
tcpBinding.TransactionFlow = false;
tcpBinding.Security.Transport.ProtectionLevel =
System.Net.Security.ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType =
TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None;

svh.AddServiceEndpoint(typeof(ServiceAssembly.IChat),tcpBinding,"net.tcp://IPAddress:3100/MyService");

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
svh.Open();

客户端设置&调用

InstanceContext context = new InstanceContext(callback);
NetTcpBinding tcpBinding = new NetTcpBinding();

tcpBinding.MaxConnections = 100;
tcpBinding.MaxBufferPoolSize = (int)4096000;
tcpBinding.MaxBufferSize = 4096000;
tcpBinding.MaxReceivedMessageSize = (int)4096000;
tcpBinding.TransactionFlow = false;
tcpBinding.OpenTimeout = new TimeSpan(0, 0, 5);
tcpBinding.CloseTimeout = new TimeSpan(0, 0, 5);
tcpBinding.SendTimeout = new TimeSpan(0, 0, 5);
tcpBinding.ReceiveTimeout = new TimeSpan(0, 0, 5);
tcpBinding.ReliableSession.Ordered = true;

tcpBinding.Security.Transport.ProtectionLevel =
    System.Net.Security.ProtectionLevel.EncryptAndSign;
tcpBinding.Security.Transport.ClientCredentialType =
    TcpClientCredentialType.Windows;
tcpBinding.Security.Mode = SecurityMode.None;

 try
 {
      scf = new DuplexChannelFactory<IChat>(context, tcpBinding,
            "net.tcp://" + m_ipAddress + ":" + m_port + "/MyService");
      s = scf.CreateChannel(); 
      s.Connect(client); <- First connection
 }
 catch
 {
     try
     {
         scf = new DuplexChannelFactory<IChat>(context, tcpBinding,
               "net.tcp://" + m_localAddress + ":" + m_port + "/MyService");
         s = scf.CreateChannel();
         s.Connect(client);
         m_ipAddress = m_localAddress;
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }

但抛出异常的超时仍然是20秒左右。更改这些值不会更改抛出异常的时间。我在下面添加了一个图像来显示调用堆栈。 enter image description here 需要任何关于如何解决这个问题或甚至改善它的建议。

1 个答案:

答案 0 :(得分:0)

我找到的解决方案帮助了我 - 不是要删除此超时,而是连接到我自己的服务器,如果本地和/或通过外部IP连接,如果不是 - 实际上是要查找进程本身。如果找到 - &gt;在本地连接,否则 - >通过给定的IP连接。 这并没有回答我的实际问题 - 但是 - 它确实解决了我的初始问题。 似乎TimeOut“延迟”是由DNS引起的,而不是我能做些什么来阻止它。

如果有人有兴趣,这是我的解决方案代码。

if (Process.GetProcessesByName("ProcessName").Length > 0)
     isLocal = true;

 if (isLocal)
     scf = new DuplexChannelFactory<IChat>(context, tcpBinding,
           "net.tcp://" + m_localAddress + ":" + m_port + "/MyService");
 else
     scf = new DuplexChannelFactory<IChat>(context, tcpBinding,
           "net.tcp://" + m_ipAddress + ":" + m_port + "/MyService");