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?