Search code examples
c#.netwcf

Notify the Multiple instances of UI using Wcf service


I have a application in WPF, which will allow me to add,delete and edit student. That UI can be opened more than once. When the UI makes change to the data through the service every other connected client should also be updated with latest changes.

Is that possible to have wcf service do it for me? How can we do it?


Solution

  • Each WPF UI window should establish a connection with the host WCF Service.

    The Service is required to be a of singleton type. Also you'll have to enable session.

    Each UI window should start have it's own connection with the service. And must also handle callback method.

    The service must track these session and callback method ID.

    Now when a UI thread makes change to the data (I am assuming using the WCF service in consideration) the service will have to iterate the session collection and send notification.

    There are only two binding that support this netTcp and WSDualHttp.

    The Service and Callback service would look as below:

    [ServiceContract(SessionMode = SessionMode.Required,
        CallbackContract = typeof(INotifyMeDataUpdate))]
    public interface IService
    {
        [OperationContract(IsInitiating=true)]
        void Register();
    
        [OperationContract(IsTerminating= true)]
        void Unregister();
    
        [OperationContract(IsOneWay=true)]
        void Message(string theMessage);
    }
    
    public interface INotifyMeDataUpdate
    {
        [OperationContract(IsOneWay=true)]
        void GetUpdateNotification(string updatedData);
    }
    

    The implementation would as below:

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class Service : IService
    {
        object _lock = new object();
        Dictionary<string, INotifyMeDataUpdate> _UiThreads =
            new Dictionary<string, INotifyMeDataUpdate>();
    
        public void Register()
        {
            string id = OperationContext.Current.SessionId;
    
            if (_UiThreads.ContainsKey(id)) _UiThreads.Remove(id);
            _UiThreads.Add(id, OperationContext.Current.GetCallbackChannel<INotifyMeDataUpdate>());
        }
    
        public void Unregister()
        {
            string id = OperationContext.Current.SessionId;
    
            if (_UiThreads.ContainsKey(id)) _UiThreads.Remove(id);
        }
    
        public void Message(string theMessage)
        {
            foreach (var key in _UiThreads.Keys)
            {
                INotifyMeDataUpdate registeredClient = _UiThreads[key];
                registeredClient.GetUpdateNotification(theMessage);
            }
        }
    }