简体   繁体   English

C#WCF NetTcpBinding超时不起作用

[英]C# WCF NetTcpBinding timeout not working

I've got a problem with the NetTcpBinding's Open, Send, Recive and Close timeouts on the initial call( [OperationContract(IsOneWay = true, IsInitiating = true)] ) Currently I'm trying to connect to a given IPAddress and if it fails I will connect to a different address. 我在初始调用时出现NetTcpBinding的打开,发送,接收和关闭超时问题( [OperationContract(IsOneWay = true, IsInitiating = true)] )当前我正在尝试连接到给定的IPAddress,如果失败我将连接到其他地址。 This is because I cannot connect to my own server through my external IP (due to NAT Loopback on my router?), and instead of having 2 versions (one for the public and one for myself) I use a Try-Catch system which tries to connect to my external IP, if it works -> continue, if it fails -> try local IP -> continue. 这是因为我无法通过外部IP连接到我自己的服务器(由于路由器上的NAT环回?),而不是使用2个版本(一个用于公共版本,一个用于我自己版本),而是使用Try-Catch系统尝试连接到我的外部IP,如果可行->继续,如果失败->尝试本地IP->继续。

The problem however is the timeout values. 但是,问题在于超时值。 Since I am waiting for an exception to be thrown and caught, I need to lower this value as much as possible (preferred 5sec) instead of the default ~20 seconds. 由于我正在等待引发和捕获异常,因此我需要尽可能降低此值(最好为5秒),而不是默认的20秒左右。

I've tried to set these values on both Client and Server side 我试图在客户端和服务器端都设置这些值

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

Server side setup: 服务器端设置:

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();

Client side setup & call 客户端设置和呼叫

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);
     }
 }

But the timeout for the exception to be thrown is still around 20 seconds. 但是抛出异常的超时时间仍然是20秒左右。 Changing these values wont change the time until the exception is thrown. 更改这些值不会更改引发异常之前的时间。 I have added an image below to show the call stack. 我在下面添加了一个图像以显示调用堆栈。 在此处输入图片说明 Any advice on how to do fix this or even make it better is wanted. 需要有关如何解决此问题或什至使其更好的任何建议。

The solution I found that helped me - not to remove this timeout, but to connect to my own server if local and/or connect over external IP if not - was to actually look for the process itself. 我发现对我有帮助的解决方案-不是删除此超时,而是在本地时连接到我自己的服务器,如果不在本地IP上则连接到我自己的服务器-实际上是在寻找进程本身。 If found -> Connect locally , else -> connect via the given IP. 如果找到->在本地连接,否则->通过给定IP连接。 This does not answer my actual question - however - it does solve my initial issue. 这不能回答我的实际问题,但是可以解决我的最初问题。 It seems that the TimeOut "delay" is due to the DNS and not something I can do to prevent it. 似乎超时“延迟”是由于DNS引起的,而不是我无法防止的事情。

Here's my solution code if anyone's interested. 如果有人感兴趣,这是我的解决方案代码。

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");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM