使用NetTcpBinding时套接字连接中止

4
我知道这个问题已经有很多相关的问题,但是没有一个答案可以解决我的问题。
我在服务器上运行了一个NetTcpBinding,但是不时地(并非总是,可能是20到60次调用之一,完全随机)客户端会收到以下异常:
“套接字连接被中止。这可能是由于处理消息或远程主机超过接收超时或底层网络资源问题而导致的。本地套接字超时为'00:01:00'。”
我注意到当客户端的连接速度较慢时,此类异常发生的频率更高。
此外,所述的超时时间为1分钟,但异常通常在1秒左右就会发生。
我的做法:
var client = GetClient();
client.Open();
bool success = client.Call(); // Exception occurs here (the return value is a bool)

有时我也会在服务器端遇到此异常:

传输数据时发生 TCP 错误(995: 由于线程退出或应用程序请求而中止 I/O 操作)。

虽然我已启用服务器跟踪,但仍然遇到相同的异常,并且没有提供任何额外的见解。

我的 GetClient 方法:

NetTcpBinding netTcpBinding = new NetTcpBinding
{
    CloseTimeout = new TimeSpan(0, 0, 30),
    OpenTimeout = new TimeSpan(0, 0, 30),
    TransferMode = TransferMode.Buffered,
    ListenBacklog = 2,
    MaxConnections = 2,
    MaxReceivedMessageSize = 10485600,
    ReaderQuotas = { MaxStringContentLength = 1048576 },
    ReliableSession = { Enabled = false },
    Security =
    {
        Mode = SecurityMode.Transport,
        Transport = { ClientCredentialType = TcpClientCredentialType.None, ProtectionLevel = ProtectionLevel.EncryptAndSign },
        Message = { ClientCredentialType = MessageCredentialType.Windows }
    }
};

服务的重要配置:

<behaviors>
    <serviceBehaviors>
        <behavior name="ServiceBehavior">
            <serviceMetadata httpGetEnabled="true" /> 
            <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true" httpsHelpPageEnabled="true" />
            <serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="My.Service.WCF.Tools.CustomAuthorizationManager, My.Service.WCF">
                <authorizationPolicies>
                    <clear/>
                    <add policyType="My.Service.WCF.Tools.CustomAuthorizationPolicy, My.Service.WCF" />
                </authorizationPolicies>
            </serviceAuthorization>
            <serviceCredentials>
                <serviceCertificate findValue="MyService" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            </serviceCredentials>
            <serviceThrottling maxConcurrentCalls="65536" maxConcurrentSessions="65536" maxConcurrentInstances="65536" />
        </behavior>
    </serviceBehaviors>
</behaviors>
<bindings>
    <customBinding>
        <binding name="ServiceBinding" receiveTimeout="00:05:00" maxConnections="65536" listenBacklog="65536">
            <transactionFlow />                      
            <sslStreamSecurity requireClientCertificate="false" />
            <binaryMessageEncoding />
            <tcpTransport transferMode="Buffered" portSharingEnabled="true" maxReceivedMessageSize="1048576" maxPendingConnections="65536" maxPendingAccepts="10">
                <connectionPoolSettings leaseTimeout="00:05:00" idleTimeout="00:05:00" maxOutboundConnectionsPerEndpoint="65536" />
            </tcpTransport>
        </binding>
        <binding name="MexBinding" receiveTimeout="00:05:00" maxConnections="65536" listenBacklog="65536"> 
            <tcpTransport transferMode="Buffered" portSharingEnabled="true" maxReceivedMessageSize="1048576" maxPendingConnections="65536" maxPendingAccepts="10">
                <connectionPoolSettings leaseTimeout="00:05:00" idleTimeout="00:05:00" maxOutboundConnectionsPerEndpoint="65536" />
            </tcpTransport>
        </binding>
    </customBinding>
</bindings>

我已经更新了服务引用并尝试更改一些缓冲区和大小,但它没有起作用(我也不指望在那里出现问题,因为只返回一个布尔值)。

使用以下方法进行修复:

OperationContext.Current.OperationCompleted += Test;

private void Test(object sender, EventArgs e)
{
    OperationContext.Current.Channel.Close();
}

不要使用Abort方法,而要使用Close方法!

你在客户端netTcpBinding上也增加了sendTimeout了吗? - Rajesh
是的,我也尝试过那个方法,但由于1分钟已经是非常长的时间了(通常一个调用只需要10毫秒左右),增加时间并没有帮助。而且,异常几乎是立即发生的,而不是在1分钟后。 - The Cookies Dog
你的客户端绑定中,开启和关闭超时时间都设置为30秒了吗? - Rajesh
是的,那是正确的。但是打开和关闭不是问题。 - The Cookies Dog
1个回答

1

我找到了问题所在:我在服务器端中止了通道。

OperationContext.Current.OperationCompleted

被称为:

OperationContext.Current.Channel.Abort();

这在99%的情况下似乎运行良好,但并非所有情况都适用:

OperationContext.Current.Channel.Close();

完全解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接