How to check the availability of a net.tcp WCF service
Asked Answered
S

5

16

My WCF server needs to go up and down on a regular basis, the client sometimes uses the server, but if it is down the client just ignore it. So each time I need to use the server services I check the connection state and if it's not open I open it. The problem is that if I attempt to open while the server is down there is a delay which hits performance. My question is, is there a way to do some kind of myClient.CanOpen()? so I'd know if there is any point to open the connection to the server.

Schwab answered 19/5, 2009 at 9:19 Comment(2)
How exactly does it hurt performance? Can you not just have the client default to disconnected mode until it successfully connects?Hatchett
When I do myClient.Open() if the server is down there is a timeout, maybe is not the exception hitting performance, I'm reediting my questionSchwab
P
24

There is an implementation of WS-Discovery that would allow you to listen for up/down announcements for your service. This is also a very convenient form of service address resolution because it utilizes UDP multicast messages to find the service, rather than configuring one set address on the client. WS-Discovery for WCF

There's also an implementation done by a Microsoft employee: WS-Discovery Sample Implementation

.NET 4.0 will include this natively. You can read about .NET 4.0's implementation on Jesus Rodriguez's blog. It has a great chart that details the ad-hoc communication that goes on in WS-Disco Using WS-Discovery in WCF 4.0

Another thing you might consider, especially if your messages are largely one-way, is a protocol that works natively disconnected, like MSMQ. I don't know what your design for your application looks like, but MSMQ would allow a client to send a message regardless of the state of the service and the service will get it when it comes back up. This way your client doesn't have to block quite so much trying to get confirmation that a service is up before communicating... it'll just fire and forget.

Hope this helps.

Psalter answered 19/5, 2009 at 16:25 Comment(1)
Cool! Thanks for expanding and explaining my thoughts and showing how it could really work.Neurosis
D
3

If you are doing a synchronous call expecting a server timeout in an application with a user interface, you should be doing it in another thread. I doubt that the performance hit is due to exception overhead. Is your performance penalty in CPU load, gui availability or wall clock time?

You could investigate to see if you can create a custom binding on TCP, but with faster timeout.

I assume you know that "IsOneWay=true" is faster than request->response in your case because you wouldn't be expecting a response anyway, but then you are not getting confirmation or return values. You could also implement a two-way communication that is not request->response.

Detrital answered 19/5, 2009 at 9:36 Comment(0)
P
1

I don't think it's possible doing a server side call to your Client to inform him that you the service has been started ... Best method i can see is having a client method figuring out where or not the service is open and in good condition. Unless I am missing some functionality of WCF ...

There is a good blogpost WCF: Availability of the WCF services if you are interested in a read.

Petterson answered 19/5, 2009 at 9:22 Comment(1)
" having a client method figuring out where or not the service is open" This is what I'm looking forSchwab
N
1

If you were in a local network it might be possible to broadcast a signal to say that a new server is up. The client would need to listen for the broadcast signal and respond accordingly.

Neurosis answered 19/5, 2009 at 10:0 Comment(1)
WS-Discovery! I'll write a response that includes this.Psalter
F
1

Here's what I'm using and it works like a charm. And btw, the ServiceController class lives in namespace 'System.ServiceProcess'.

try
{
    ServiceController sc = new ServiceController("Service Name", "Computer's IP Address");
    Console.WriteLine("The service status is currently set to {0}",
        sc.Status.ToString());

    if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
        (sc.Status.Equals(ServiceControllerStatus.StopPending)))
    {
        Console.WriteLine("Service is Stopped, Ending the application...");
        Console.Read();
        EndApplication();
    }
    else
    {
        Console.WriteLine("Service is Started...");
    }
}
catch (Exception)
{
    Console.WriteLine("Error Occurred trying to access the Server service...");
    Console.Read();
    EndApplication();
}
Frizzly answered 11/3, 2014 at 22:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.