WCF Duplex中客户端突然崩溃怎么办

Posted

技术标签:

【中文标题】WCF Duplex中客户端突然崩溃怎么办【英文标题】:What Should I Do When Client Suddenly Crashes in WCF Duplex 【发布时间】:2016-05-14 06:45:26 【问题描述】:

我使用 WCF Duplex 在服务器中订阅 WCF 的用户之间发送/接收消息。 WCF 有三种方法:Join(订阅)、Leave(取消订阅)和 SendAlert(从一个用户向其他用户发送消息)。以下是服务器端代码(AlertService in WCF duplex in server):

using System;
using System.Collections.Generic;
using System.ServiceModel;

namespace RahatWCF

    [ServiceContract(Name = "AlertService",
                     Namespace = "RahatWCF",
                     SessionMode = SessionMode.Required,
                     CallbackContract = typeof(IAlertCallback))]
    public interface IAlert
    
        [OperationContract]
        int JoinTheConversation(int userId);

        [OperationContract(IsOneWay = true)]
        void SendAlert(int senderUserId, List<int> recieversUserId, string caption, string messageText);

        [OperationContract]
        int LeaveTheConversation(int userId);
    

    public interface IAlertCallback
    
        [OperationContract(IsOneWay = true)]
        void NotifyUserOfMessage(int senderUserId, List<int> recieversUserId, string caption, String messageText);
    

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerCall)]
    public class AlertService : IAlert
    
        private static List<IAlertCallback> _callbackList = new List<IAlertCallback>();

        public AlertService()  

        public int JoinTheConversation(int userId)
        
            IAlertCallback registeredUser = OperationContext.Current.GetCallbackChannel<IAlertCallback>();

            if (!_callbackList.Contains(registeredUser))
                _callbackList.Add(registeredUser);

            return _callbackList.Count;
        

        public int LeaveTheConversation(int userId)
        
            IAlertCallback registeredUser = OperationContext.Current.GetCallbackChannel<IAlertCallback>();

            if (_callbackList.Contains(registeredUser))
                _callbackList.Remove(registeredUser);

            return _callbackList.Count;
        

        public void SendAlert(int senderUserId, List<int> recieversUserId, string caption, string messageText)
        
            _callbackList.ForEach(
                delegate (IAlertCallback callback)
                
                    callback.NotifyUserOfMessage(senderUserId, recieversUserId, caption, messageText);
                );
        
    

上面的代码是我在服务器端实现的 WCF Duplex。当用户登录应用程序时,我的 WCF 客户端应用程序会加入此 WCF;当用户从应用程序注销时,客户端应用程序会离开 WCF。问题是,如果用户突然终止应用程序并且没有从客户端应用程序注销,那么他/她以后无法向其他用户发送消息。我检查了这个问题,发现当用户登录(加入)并且没有注销(离开)时,在服务器中为用户创建了两个通道,并且 SendAlert 在这种情况下不再起作用。我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

超时是双工通道的关键设置(如果没有消息发送或接收)。保持简短,您的频道将出现故障。如果您从服务器发送响应,您可以对错误的客户端通道做出反应并将其从已知通道中删除。如果客户端出现故障,则需要重新加入服务器;在这种情况下,您可以从服务中删除其他回调。

【讨论】:

我增加了“receiveTimeout”和“inactivityTimeout”,但有时(我不知道为什么)我收到错误消息“无法使用通信对象 System.ServiceModel.Channels.ServiceChannel用于通信,因为它已被中止。我该如何解决这个错误? 你可以看看re-connect logic,但你唯一能做的就是重新创建频道。 谢谢。我会检查并通知您。

以上是关于WCF Duplex中客户端突然崩溃怎么办的主要内容,如果未能解决你的问题,请参考以下文章

使用 WCF Duplex 回调更新 JQuery 进度条?

从不同线程调用时,WCF Duplex 回调方法永远不会执行

Duplex or request-reply with Apache ActiveMQ WCF Binding 配置问题

WCF系列WCF客户端怎么消费服务

C#客户端 怎么知道wcf服务 已关闭

WCF系列教程之消息交换模式之请求与答复模式(Request/Reply)