Search code examples
c#wcfnettcpbindingduplex

Can I Subscribe using one channel and publish on a seperate channel WCF?


I have a subscribe - publish WCF service, the service is hosted in a Windows Service. The data the Windows Service processes is being sent to subscribed clients. For some methods I need to use callbacks to Client Request from Service. However I also need to publish the data the Service is continuously generating through it's tasks (once per second sending updates to the clients). Using the Callback method to do this you guessed it when more than one method is sending lots of data I get a crash of the communicationobject. I read this WCF CallBack Blocks other Callbacks , which for him worked - in my scenario I have multiple methods pushing data (about 30 rows x 12C) every 1 second. Since my Client hangs and the CommunicationObject goes bust I can not send. I would like to know if I can just have a DuplexChannel for the subscribing and general functions and then when I need to publish just add a separate Channel maybe create it on the fly in the service and send the data? If there is anyone with any experience or samples of this I would appreciate it.

Or maybe you can tell me I am all wrong in this and WCF will send callbacks at this rate to multiple methods with no problems and here is a sample how to do that. My current settings are: It is a singleton service - running 24/7 subscribers are stored in a dictionary. InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode = Multiple, UseSynchronizationContext=true NetTcpBinding. Any help is appreciated.


Solution

  • I am posting the answer which I came up with so that others may benefit. After searching and searching - I came across pieces of the answer and the light bulb started coming on. The parts for me that did the magic was instantiating my Service with an Instance of the Service - rather than a typeof the Service. I did need to change my code in the ServiceHost when adding my behaviours and bindings - because when you use typeof and uri binding - WCF sets some defaults and when I use ServiceInstance - it does not set those defaults. Unfortunately I forgot what it 'automagically' did for me; but it is on MSDN.

    Anyway DuplexClient works and Callbacks also work very well. Error Handling was a bit over the top in my ServiceClass but otherwise straight forward.

    To publish from your Hosting Service whether console or Windows Service; the following code did the trick for me. the ServerContract has InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode = Multiple, UseSynchronizationContext=true

    class Publishing
    {
    public static ServerContract PublishService { get; set; }
    
    public static iSortClientContracts.WCF.ServerProxy WCF_Server { get; set; }
    
    void Publish()
    {
    // Create the Instance of the Service Class.
    serverContract = new ServerContract(); 
    // Create the Service Host using the INSTANCE I just created.
    WCF.Server.ServerHost<WCF.Contracts.ServerContract> WCFServerHost = new WCF.Server.ServerHost<WCF.Contracts.ServerContract>(serverContract, baseAddress); // I am using NetTcpBinding in case someone would like to know.
    
    // Get the Singleton Instance [InstanceMode.Singleton Pattern]
    PublishService = (ServerContract)WCF_Server.SingletonInstance;
    
    List<products> productList = new List<products>(new Product(), new Product());
    
    System.ServiceModel.Channels.CommunicationObject comm = WCF_Server;
    if (comm.State == CommunicationState.Opened)
    {                    
          PublishService.PushProductsToClients(productList);                     
    }
    
    }
    }
    

    I was publishing several types of data at intervals of once per second.. I have to say this works way better than I thought. I only require a max of 3 clients - but successfully had 13 clients connected using 1.2% CPU max each [No Crashes not even a catch - which is what I needed.] and the servicehost was wasn't even breaking a sweat!