WCF NetTcp ホストを収容する Windows サービスがあります。クライアントから、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);
});