YaKs
YaKs

Reputation: 329

C# How to force the wait for the connection to a WCF service

I have a service running as local SYSTEM that launches another application with the user credentials. That second app is only a tray icon that shows balloon tips to the user with the string received using the callback method. This second application connects to the WCF in duplex mode.

My problem is that for some reason the connection to the WCF is finalized at the end of the method Main. So I cannot send a callback message to the app right after the execution, included in the last line "kiosk.MyStart(args);". there the callback is still pointing to null.

Any idea how could I solve this issue?

static void Main(string []args)
{
    if (Environment.UserInteractive)
    {
         // Start the WCf service
         var host = new ServiceHost(typeof(WcfService));
         host.Open();

         //Launch the Kiosk Agent which connects to the WCF
         bool ret = ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");
         WinService kiosk = new WinService(args);
         // some checks and a welcome message is sent to the user.
         kiosk.MyStart(args);

         //...
         //...
    }
}

Edit: to clarify a bit more, inside kiosk.MyStart method is where I try to execute the callback to show a welcome message, but the callback is still NULL. As a result I assume that the client was not properly started for any reason and I launch it once again...

            if (WcfService.Callback != null)
                WcfService.Callback.UIMessageOnCallback(UIMessage);
            else
                ProcessAsUser.Launch("C:\\Program Files (x86)\\KIOSK\\KioskAgent.exe");

Upvotes: 0

Views: 385

Answers (1)

live2
live2

Reputation: 4265

Add a try catch block over the callback method, if the client not reachable it falls in the catch you can unsubscribe it. Is also good practice send a keepalive message to your client, to check if it available.

private void InformClient(ClientInfo clientInfo)
{
    var subscribers = this._subscriberRepository.GetAll();
    foreach (var subscriber in subscribers)
    {
        try
        {
            if (subscriber.Callback.FireInformClient(clientInfo));
            {
                //If subscriber not reachable, unsubscribe it
                this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            }
        }
        catch (Exception exception)
        {
            //If subscriber not reachable, unsubscribe it
            this._subscriberRepository.Unsubscribe(subscriber.ClientId);
            Log.Error(nameof(InformClient), exception);
        }
    }
}

IClientCallback

public interface IClientCallback
{
    [OperationContract]
    bool FireInformClient(ClientInfo clientInfo);
}

If you have more subscribers for example a terminal, server create a subscriberRepository to manage all subscribers.

var callback = OperationContext.Current.GetCallbackChannel<IClientCallback>();
if (this._subscriberRepository.Subscribe(clientId, callback))
{
    return true;
}

Upvotes: 1

Related Questions