我正在开发一个ASP.NET MVC项目,并发现了几个未关闭的WCF服务连接,我认为这会导致TCP / IP端口耗尽。
我在资源监视器/网络/ TCP连接上检查了服务器,并且有数千个灰色连接作为" IPV6 Loopback"在某些时候,有很多连接,服务器停止响应服务端口。
存在一个依赖注入来处理控制器上的连接,并且有一个" CloseChannel"方法,但它没有调用,我对它做了一些更改,并开始在控制器上的Dipose方法中调用它来关闭连接,但我没有得到任何结果。环回继续出现。
我认为要做的两个解决方案是:
删除依赖注入并正常创建连接 在每次使用时。
除了关闭连接之外,还要对服务器进行一些更改 在此post
的疑问: 有没有比我提议的更好的选择?如果没有,您认为哪一个最好?
谢谢大家!
PS:今天用于打开和关闭连接的代码:
在控制器上调用:
IClient wcfClient = WcfChannel.CreateChannel<IClient>(connectionstr, WcfChannel.WcfBinding.NetTcpBinding);
这是WcfChannel:
public static class WcfChannel
{
public static T CreateChannel<T>(string endpointAddress, WcfBinding wcfBinding)
{
Binding binding = null;
#region ReaderQuotas
XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas()
{
MaxDepth = int.MaxValue,
MaxStringContentLength = int.MaxValue,
MaxArrayLength = int.MaxValue,
MaxBytesPerRead = int.MaxValue,
MaxNameTableCharCount = int.MaxValue
};
#endregion
switch (wcfBinding)
{
case WcfBinding.BasicHttpBinding:
case WcfBinding.NetMsmqBinding:
case WcfBinding.NetNamedPipeBinding:
throw new NotImplementedException();
case WcfBinding.NetTcpBinding:
binding = new NetTcpBinding()
{
Name = "NetTcpBinding",
MaxBufferPoolSize = long.MaxValue,
MaxBufferSize = int.MaxValue,
MaxReceivedMessageSize = int.MaxValue,
ReaderQuotas = readerQuotas,
Security = new NetTcpSecurity() { Mode = SecurityMode.None },
CloseTimeout = new TimeSpan(0, 5, 0),
OpenTimeout = new TimeSpan(0, 5, 0),
ReceiveTimeout = new TimeSpan(0, 5, 0),
SendTimeout = new TimeSpan(0, 5, 0)
};
break;
case WcfBinding.NetTcpBindingStreamed:
binding = new NetTcpBinding()
{
Name = "NetTcpBindingStreamed",
TransferMode = TransferMode.Streamed,
MaxBufferPoolSize = long.MaxValue,
MaxBufferSize = int.MaxValue,
MaxReceivedMessageSize = int.MaxValue,
ReaderQuotas = readerQuotas,
Security = new NetTcpSecurity() { Mode = SecurityMode.None },
CloseTimeout = new TimeSpan(0, 5, 0),
OpenTimeout = new TimeSpan(0, 5, 0),
ReceiveTimeout = new TimeSpan(0, 5, 0),
SendTimeout = new TimeSpan(0, 5, 0)
};
break;
case WcfBinding.WS2007HttpBinding:
case WcfBinding.WSHttpBinding:
throw new NotImplementedException();
default:
throw new NotImplementedException();
}
EndpointAddress endpoint = new EndpointAddress(endpointAddress);
var channelFactory = new ChannelFactory<T>(binding, endpoint);
T channelObj = channelFactory.CreateChannel();
return channelObj;
}
public static void CloseChannel(this object obj)
{
if (obj != null)
{
try
{
(obj as IClientChannel).Close();
}
catch (CommunicationException)
{
if (obj.GetType().GetMethod("Abort") != null)
{
(obj as IClientChannel).Abort();
}
}
catch (TimeoutException)
{
if (obj.GetType().GetMethod("Abort") != null)
{
(obj as IClientChannel).Abort();
}
}
catch (Exception)
{
//many connections doesn't have and Abort or close
}
if (obj.GetType().GetMethod("Dispose") != null)
{
(obj as IDisposable).Dispose();
}
obj = null;
}
}
public enum WcfBinding
{
BasicHttpBinding,
NetMsmqBinding,
NetNamedPipeBinding,
NetTcpBinding,
NetTcpBindingStreamed,
WS2007HttpBinding,
WSHttpBinding
}
}
答案 0 :(得分:0)
我怀疑您的问题是由于未管理WCF会话而产生的。 Net TCP绑定是基于会话的绑定,需要管理会话。与ASP.NET相比,会话由服务器启动和管理,在WCF中,会话由客户端启动和管理。 您可以使用ServiceContract / SessionMode,OperationContract / IsInitiating / IsTerminating注释属性来管理会话。 (此处的文档:https://docs.microsoft.com/en-us/dotnet/framework/wcf/using-sessions)
在客户端,您需要在结束会话后调用CloseChannel方法。此外,您需要验证所有异常的通道状态并调用abort方法(关于在此使用Net TCP绑定客户端的一些考虑因素:https://blogs.msdn.microsoft.com/rodneyviana/2016/02/29/considerations-for-nettcpbindingnetnamedpipebinding-you-may-not-be-aware/)。此外,在服务器端,作为最佳实践,可能需要启用服务限制以限制会话/服务实例(https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/using-servicethrottlingbehavior-to-control-wcf-service-performance)。