I have C# based client-server architecture. The client will connect to server and exchange data.
I need to check the server status continuously and if the server goes down (removed from the network or shut down) the client needs to indicate that.
If I am using Ping utility in the client program, which will be the best method in terms of performance i.e, monitor via a separate thread or through a background class?
public static bool GetPingResponse(string IpAddress, int timeout = 3000)
{
var ping = new Ping();
var reply = ping.Send(IpAddress, timeout);
if (reply.Status == IPStatus.Success)
{
return true;
}
else
{
return false;
}
}
Is there any other option better than Ping in terms of performance and consuming the resource?
You'll want to make sure your call is representative of "being available". For example, if it's an http server, making a ping request just says it's reachable via the network. The web server could be down but the network stack is up. If that's the case, make a call to something that exercises more of the stack like http. If there's backend databases, the call could go through to the database server. It all depends on your definition of "available". If the point is to say the application is available, you should look into a call that exercises a path through the full stack.
It also depends on what the server has available and what's open via firewalls between the clients and the servers.
Ping uses ICMP which some sites choose to block via firewalls. If that's open, it's a cheap call with little overhead.
If that's blocked and it's a web server for example over http, you could have a cheap endpoint on the web server that you could call via http client in C#.
You'll want to poll on a background thread probably with a timer. Look into the BackgroundWorker class or ThreadPool.QueueUserWorkitem.
Finally, you could look into a monitoring solution - there's many out there which could monitor multiple facets of your server(s). If you go that route, the client could simply query the monitoring solution which might be better since you wouldn't have n clients polling your servers - just one monitoring stack.
On a side note, the last block of code can be simplified down to:
return reply.Status == IPStatus.Success;
Related
I have about 500 web services. I tired to use Ping but it dont seem to be accurate. I have tested web client and download to string. Using stopwatch i calculated the download time. Its also not so accurate. What is the best method to identify the availability of the web service?
Stopwatch sw = new Stopwatch();
sw.Start();
pingable = a.IsAddressAvailable(nameOrAddress);
sw.Stop();
public bool IsAddressAvailable(string address)
{
try
{
System.Net.WebClient client = new WebClient();
client.DownloadData(address);
return true;
}
catch
{
return false;
}
}
You can create an Endpoint returning the status of your services. You can call this particular webservice time to time to check availability. If the server dont answer for a predetermined number of retries) you can consider it Down.
Its a webservice to check server and services status.
You will need to think about setting up a healthcheck strategy.
Depends on the layer, you want to check:
Network availability? Ping should be enough, as long as the ICMP packets are not rejected on their way by any firewall. Maybe not a really meaningful test.
Socket/application server availability? A simple recurring socket connection check (for examples, see Java detect lost connection) is the most efficient way of checking, if there is a listener up and running on your application server. But in some cases, this test is not enough in case the http server of your webservice is up and running, but your webservice has for instance issues behind (database problems for instance)
Functional availability? The most reliable but also most complex strategy. You will need to a) implement a ping service on the soap-layer of your webservice or b) invoke existing webservice operations for checking their availability. But, you must be careful when invoking writing services. Either you design them in an idempotent manner (retries/duplicate requests don't change anything), or you prepare some functional harmless invalid request towards your write services and make an assert on your healtcheck-client against the response.
I am building a c#/wpf project.
It's architecture is this:
A console application which will be on a virtual machine (or my home computer) that will be the server side.
A wpf application that will be the client app.
Now my problem is this - I want the server to be able to send changes to the clients. If for example I have a change for client ABC, I want the server to know how to call a service on the clients computer.
The problem is, that I don't know how the server will call the clients.
A small example in case I didn't explain it well:
The server is on computer 1, and there are two clients, on computers 2 and 3.
Client 2 has a Toyota car and client 3 has a BMW car.
The server on computer 1 wants to tell client 2 that it has a new car, an Avenger.
How do I keep track and call services on the clients?
I thought of saving their ip address (from calling ipconfig from the cmd) in the DB - but isn't that based on the WI-FI/network they are connected to?
Thanks for any help!
You could try implementing SignalR. It is a great library that uses web sockets to push data to clients.
Edit:
SignalR can help you solve your problem by allowing you to set up Hubs on your console app (server) that WPF application (clients) can connect to. When the clients start up you will register them with a specified Hub. When something changes on the server, you can push from the server Hub to the client. The client will receive the information from the server and allow you to handle it as you see fit.
Rough mockup of some code:
namepsace Server{}
public class YourHub : Hub {
public void SomeHubMethod(string userName) {
//clientMethodToCall is a method in the WPF application that
//will be called. Client needs to be registered to hub first.
Clients.User(userName).clientMethodToCall("This is a test.");
//One issue you may face is mapping client connections.
//There are a couple different ways/methodologies to do this.
//Just figure what will work best for you.
}
}
}
namespace Client{
public class HubService{
public IHubProxy CreateHubProxy(){
var hubConnection = new HubConnection("http://serverAddress:serverPort/");
IHubProxy yourHubProxy = hubConnection.CreateHubProxy("YourHub");
return yourHubProxy;
}
}
}
Then in your WPF window:
var hubService = new HubService();
var yourHubProxy = hubService.CreateHubProxy();
yourHubProxy.Start().Wait();
yourHubProxy.On("clientMethodToCall", () => DoSometingWithServerData());
You need to create some kind of subscription model for the clients to the server to handle a Publish-Subscribe channel (see http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html). The basic architecture is this:
Client sends a request to the messaging channel to register itself as a subscriber to a certain kind of message/event/etc.
Server sends messages to the channel to be delivered to subscribers to that message.
There are many ways to handle this. You could use some of the Azure services (like Event hub, or Topic) if you don't want to reinvent the wheel here. You could also have your server application track all of these things (updates to IP addresses, updates to subscription interest, making sure that messages don't get sent more than once; taking care of message durability [making sure messages get delivered even if the client is offline when the message gets created]).
In general, whatever solution you choose is plagued with a common problem - clients hide behind firewalls and have dynamic IP addresses. This makes it difficult (I've heard of technologies claiming to overcome this but haven't seen any in action) for a server to push to a client.
In reality, the client talks and the server listens and response. However, you can use this approach to simulate a push by;
1. polling (the client periodically asks for information)
2. long polling (the client asks for information and the server holds onto the request until information arrives or a timeout occurs)
3. sockets (the client requests server connection that is used for bi-directional communication for a period of time).
Knowing those terms, your next choice is to write your own or use a third-party service (azure, amazon, other) to deliver messages for you. I personally like long polling because it is easy to implement. In my application, I have the following setup.
A web API server on Azure with and endpoint that listens for message requests
A simple loop inside the server code that checks the database for new messages every 100ms.
A client that calls the API, handling the response.
As mentioned, there are many ways to do this. In your particular case, one way would be as follows.
Client A calls server API to listen for message
Server holds onto call, waiting for new message entry in database
Client B calls server API to post new message
Server saves message to database
Server instance from step 2 sees new message
Server returns message to Client A.
Also, the message doesn't have to be stored in a database - it just depends on your needs.
Sounds like you want to track users à la https://www.simple-talk.com/dotnet/asp.net/tracking-online-users-with-signalr/ , but in a desktop app in the sense of http://www.codeproject.com/Articles/804770/Implementing-SignalR-in-Desktop-Applications or damienbod.wordpress.com/2013/11/20/signalr-a-complete-wpf-client-using-mvvm/ .
The project I'm working on is a client-server application with all services written in WCF and the client in WPF. There are cases where the server needs to push information to the client. I initially though about using WCF Duplex Services, but after doing some research online, I figured a lot of people are avoiding it for many reasons.
The next thing I thought about was having the client create a host connection, so that the server could use that to make a service call to the client. The problem however, is that the application is deployed over the internet, so that approach requires configuring the firewall to allow incoming traffic and since most of the users are regular users, that might also require configuring the router to allow port forwarding, which again is a hassle for the user.
My third option is that in the client, spawns a background thread which makes a call to the GetNotifications() method on server. This method on the server side then, blocks until an actual notification is created, then the thread is notified (using an AutoResetEvent object maybe?) and the information gets sent to the client. The idea is something like this:
Client
private void InitializeListener()
{
Task.Factory.StartNew(() =>
{
while (true)
{
var notification = server.GetNotifications();
// Display the notification.
}
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
Server
public NotificationObject GetNotifications()
{
while (true)
{
notificationEvent.WaitOne();
return someNotificationObject;
}
}
private void NotificationCreated()
{
// Inform the client of this event.
notificationEvent.Set();
}
In this case, NotificationCreated() is a callback method called when the server needs to send information to the client.
What do you think about this approach? Is this scalable at all?
For each client you are going to hold a thread on the server. If you have a few hundred clients and the server wouldn't use the memory anyway, that may be fine. If there can be more clients, or you do not wish to burn 1MB of stack per client, you should make some changes:
Use an async WCF action method. They allow you to unblock the request thread while the method is waiting.
Change the event model to an async once. SemaphoreSlim has async support. You can also use TaskCompletionSource.
That way you can scale up to many connections.
I have a server and a website running 100% fine.
The thing is, I want my website to show on the default page "Status" of the server. I was thinking about pinging the server with this code:
Uri url = new Uri("http://www.abhigrgrgrgrgsheksur.com");
string pingurl = string.Format("{0}", url.Host);
string host = pingurl;
bool result = false;
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
return true;
}
catch { }
return result;
The code is from a website I found online, not mine.
The thing is, if you put that code on the default page on the website, when people do "Reverse" its always pings the server, my question is, can it drop the server? Or get it stop working? Or anything like that? The server is not a website. It's a running process (MineCraft Server).
If I understood correctly your worried about on every refresh of page it will ping and multiple ping call will be made
So the statement made in Remarks paragraph for Ping Class at http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx might help your concern
You cannot use the same instance of the Ping class to generate multiple simultaneous ICMP Echo requests. Calling Send while a SendAsync call is in progress or calling SendAsync multiple times before all previous calls have completed causes an InvalidOperationException.
It will send multiple ping requests to the server. That's shouldn't make the server crash. Although you might need to check with your network administrator whether multiple PING requests form the same IP (the IP of your web server) won't be dropped by some firewall for example.
I am designing a webservice interface for use between a Windows CE device and a PC. The Windows CE device is server and the PC is client.
I have decided to use the gSOAP library to implement the server and I am using .NET/C# for the client. I have followed the approach described here and everything is working well.
My question is about how to best implement an asynchronous callback/event from the server to the client. I can think of two methods:
Continuously polling the server for active events
A blocking method that keeps the connection open until an event occurs
I have currently chosen option 2 and it seems to be working well. I use an asynchronous method in the client and therefore get a callback when the method completes, i.e. when an event occurs on the Windows CE device. I then immediately call the same method again so it is ready for the next event.
Example server method (no error handling):
int ns__WaitForEvent(struct soap* soap, int *eventId)
{
WaitForSingleObject(hMyServerEvent, INFINITE);
*eventId = GetCurrentEventId();
return SOAP_OK;
}
Example client (no error handling):
private void SubscribeToServerEvents()
{
var server = new MyMethods.ServicePortTypeClient(
new BasicHttpBinding(),
new EndpointAddress(myIpAddress));
AsyncCallback cb = this.Callback;
server.BeginWaitForEvent(cb, server);
}
private void Callback(IAsyncResult ar)
{
var server = (MyMethods.ServicePortType)ar.AsyncState;
var result = server.EndWaitForEvent(ar);
// Do stuff with result
}
The server must be multi-threaded for this approach to work, and the number of clients should be limited so the server does not have a large number of threads hanging with blocking methods. In my case none of these issues are a problem - it is simple to setup a multi-threaded server using gSOAP and there will only ever be one client (which I control) attached to each server.
Are there any significant disadvantages to this approach? Can you suggest a better solution?
I suggest to turn the WinCE device into a webclient instead of a webserver and the PC into a server, that will be notified on something happens on the client. It is more natural this approach, you can still use gSoap for a soap client. On the PC you should have a web-server like Apache or IIS installed, or you could make a Windows server that will host an embedded light webserver.