简体   繁体   中英

What Should I Do When Client Suddenly Crashes in WCF Duplex

I use WCF Duplex to send/receive messages among users who subscribed in WCF in server. The WCF has three methods: Join (to subscribe), Leave (to unsubscribe) and SendAlert (to send message from a user to other users). The following is the server side code (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);
                });
        }
    }
}

The above code is WCF Duplex that I implemented in server side. My WCF client application joins this WCF when the user logins into the app; And the client app leaves the WCF when the user logouts from the app. The problem is that if user suddenly terminates the app and not logout from client app then he/she cannot send message to other users later. I checked the issue and find out that when a user logins (joins) and does not logout (leave) then in server two channels are created for user and SendAlert does not work anymore in this situations. How can I solve this problem?

Timeout is the key setting for duplex channels (if there are no messages sent or received). Keep them short and your channel will fault. If you send a response from the server you can react on faulted client channel and remove it from known channels. If client faults than it needs to re-join the server; which in that case you could remove other callbacks from your service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM