У меня есть служба Windows, в которой находится хост WCF NetTcp.С клиента, когда я начинаю звонить в службу через tcp, сначала они проходят нормально, но затем, через несколько минут, все начинают выдавать страшную ошибку тайм-аута WCF, которая на самом деле не имеет ничего общего с тайм-аутами:
Эта операция запроса отправлена на net.tcp: // myserver: 8080 / ListingService не получил ответ в течение настроенного времени ожидания (00:01:00).
У меня естьИз других постов на этом сайте видно, что во многих случаях это связано с максимальными размерами сообщений, но я уже установил эти ограничения безрезультатно.
Вот мой код службы Windows:
public partial class Service : ServiceBase
{
internal static ServiceHost myHost = null;
public Service()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
System.Net.ServicePointManager.DefaultConnectionLimit = 10000;
//create host.
var path = ConfigurationManager.AppSettings["ServiceHostAddress"].ToString();
myHost = new ServiceHost(typeof(ListingService));
//add endpoint.
myHost.AddServiceEndpoint(typeof(IListingService), GetBinding(), path);
//add behaviors.
AddBehaviors();
//open host.
myHost.Open();
}
private void AddBehaviors()
{
//service metadata behavior.
var smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
myHost.Description.Behaviors.Add(smb);
//service throttling behavior.
var behavior = new ServiceThrottlingBehavior()
{
MaxConcurrentCalls = 10000,
MaxConcurrentInstances = 10000,
MaxConcurrentSessions = 10000
};
myHost.Description.Behaviors.Add(behavior);
//service debug behavior.
var serviceDebugBehavior = myHost.Description.Behaviors.Find<ServiceDebugBehavior>();
serviceDebugBehavior.IncludeExceptionDetailInFaults = true;
}
private Binding GetBinding()
{
var queueBinding = new NetTcpBinding(SecurityMode.None);
queueBinding.MaxConnections = 10000;
queueBinding.MaxBufferSize = 2048000;
queueBinding.MaxReceivedMessageSize = 2048000;
return queueBinding;
}
protected override void OnStop()
{
if (myHost != null)
{
myHost.Close();
myHost = null;
}
}
}
Вот конфиг клиента на случай, если он что-то изменит:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding" transferMode="Buffered" hostNameComparisonMode="StrongWildcard"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"><!-- transactionFlow="true"-->
<security mode="None"/>
<reliableSession enabled="false"/>
<readerQuotas maxArrayLength="2147483647"/>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint
address="net.tcp://myserver:8080/ListingService"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding"
contract="ListingServiceProxy.IListingService" name="NetTcpBinding" />
</client>
</system.serviceModel>
Я обязательно закрою свои клиентские соединения, вот код:
public static void Using<T>(this T client, Action<T> work)
where T : ICommunicationObject
{
try
{
work(client);
client.Close();
}
catch (CommunicationException)
{
client.Abort();
throw;
}
catch (TimeoutException)
{
client.Abort();
throw;
}
catch
{
client.Abort();
throw;
}
}
new ListingServiceClient().Using(client =>
{
client.SaveListing(listing);
});