none
HOW TO get list of ClientChannel(s) when InstanceContextMode = Single

    Question

  • I have a service that is a multi-threaded singleton:

    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]

    I also want to implement a duplex contract on this service so that the service can notify any clients of service-specific state changes.

    How do I [from within the service instance logic] dynamically get the currently connected client channels' callback interfaces - so that I can run down through them calling the state-changed handler operation?  Or, is there an event that I can hook into in my service that would notify me when a client connects/disconnects?  This would allow me to maintain the collection of callback interfaces - if the core WCF implementation does not provide this.

    Thanks,

    Bob

    Monday, February 05, 2007 8:40 PM

Answers

  • Bob,

    You need to keep track of the clients on the server. Here is how I implement this

      //create a list used to keep track of clients
       List<ICallbackContract> _ClientCallbacks = new List<ICallbackContract>();

       //client calls this to register itself with service
        //note: this could be implemented directly in your method
       public void RegisterCallback()
       {
          //get client callback channel
          ICallbackContract clientCallback = OperationContext.Current.GetCallbackChannel<ICallbackContract>();
          if(_ClientCallbacks.Contains(clientCallback) == false)
          {
             //add to list
              _ClientCallback.Add(clientCallback);
          }
       }

      
       //call all clients
       static public void CallAllClients()
       {
          Action<ICallbackContract> invoke = delegate(ICallbackContract clientCallback)
                                                 {
                                                    clientCallback.OnCallback();
                                                 };
          _ClientCallbacks.ForEach(invoke);
       }


    Does this make sense? Hope it helps.

    note: Parts of this code based on the works of the guys over at IDesign.

    Tuesday, February 06, 2007 12:33 AM

All replies

  • Bob,

    You need to keep track of the clients on the server. Here is how I implement this

      //create a list used to keep track of clients
       List<ICallbackContract> _ClientCallbacks = new List<ICallbackContract>();

       //client calls this to register itself with service
        //note: this could be implemented directly in your method
       public void RegisterCallback()
       {
          //get client callback channel
          ICallbackContract clientCallback = OperationContext.Current.GetCallbackChannel<ICallbackContract>();
          if(_ClientCallbacks.Contains(clientCallback) == false)
          {
             //add to list
              _ClientCallback.Add(clientCallback);
          }
       }

      
       //call all clients
       static public void CallAllClients()
       {
          Action<ICallbackContract> invoke = delegate(ICallbackContract clientCallback)
                                                 {
                                                    clientCallback.OnCallback();
                                                 };
          _ClientCallbacks.ForEach(invoke);
       }


    Does this make sense? Hope it helps.

    note: Parts of this code based on the works of the guys over at IDesign.

    Tuesday, February 06, 2007 12:33 AM
  • Michael,

     

    Thanks for the quick response!  This worked out well!  I especially like the anonymous delegates.  I've never used those before - nor the collection's ForEach method. 

     

    Regards,

    Bob

    Wednesday, February 07, 2007 12:14 PM