2

环境

WCF 服务 (NET:TCP | Reliable | SecurityEnabled) 在物理机 A 上作为控制台运行

有 20-30 个 .NET 客户端应用程序 (Winforms) 暴露在 Citrix 上,因此再次托管在与服务器不同的一台物理机器上。

问题

应用程序结构遵循与Juval Lowy在http://msdn.microsoft.com/en-us/magazine/cc163537.aspx中讨论的相同模式。

问题出在服务器上,它能够毫无错误地调用回调,但客户端永远不会收到它。如果在 60 秒内没有回调调用,则有代码尝试再次订阅。它的副作用是它通过调用服务器上的订阅 API 打开一个新连接。在一段时间内,您可以看到服务器上打开了许多 TCP 连接。没有错误,但仍然永远不会调用客户端回调。

附加信息

有时会抛出以下错误:

无法在分配的超时时间 00:01:00 内传输消息。可靠通道的传输窗口中没有可用空间。分配给此操作的时间可能是较长超时的一部分。

此外,MaxBufferPoolSize 设置为 Int64.MaxValue,如下面的代码所示

var binding = new NetTcpBinding(SecurityMode.Transport, reliableSession);
binding.ReliableSession.Enabled = true;
binding.ReliableSession.InactivityTimeout = TimeSpan.FromDays(1);
binding.ReliableSession.Ordered = true;
binding.CloseTimeout = TimeSpan.FromHours(1);
binding.SendTimeout = TimeSpan.FromHours(1);
binding.ReceiveTimeout = TimeSpan.FromHours(1);
binding.OpenTimeout = TimeSpan.FromHours(1);
binding.ReaderQuotas.MaxDepth = Int32.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.ReaderQuotas.MaxArrayLength = Int32.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = Int32.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = Int32.MaxValue;
binding.MaxBufferPoolSize = Int64.MaxValue;
binding.MaxReceivedMessageSize = Int32.MaxValue;

任何建议都会有很大帮助!

4

2 回答 2

3

最近的发现:

我最近发现客户端的回调根据用户屏幕上的可见内容进行了不同类型的处理。这阻止了要确认的回调。这也解释了缓冲区溢出。与每个客户端处理它们所花费的时间相比,从服务器发送通知的频率非常高。

除了我所做的更改(例如禁用安全性、正确配置超时)之外,以下代码行有很大帮助:

   public void OnNotification(AmigoMessage messsage)
    {
        ThreadPool.QueueUserWorkItem((x) => { ProcessNotification(messsage); });
    }
于 2013-02-28T12:16:30.837 回答
1

看看[CallbackBehavior(UseSynchronizationContext = false)]。回调服务上没有此属性将尝试(通常)编组到 UI 线程。

于 2014-12-23T17:14:14.940 回答