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.
Related
I will be deploying my first application based on WCF and would like to know the best way to deploy. Here is my architecture. Please see the attached image.
We have a WCF written using 4.0 framework and has 3 methods. A front end ASP.NET website (www.site.com) calls the WCF to save data as well as read data. In figure method1 is saving to data and method2 and 3 are for reading the data from SQL server 2008 R2 database.
In my ASP.Net webstie...
I am calling the Method1 and closing the connection...like this..
ServiceClient client = new ServiceClient();
client.Method1(data to be saved)
client.close();
I am calling method 2 and 3 as follows
ServiceClient client = new ServiceClient();
dropDown1list.datasource = client.Method2()
dropDown2list.datasource = client.Method3()
client.close();
Multiple users could be using the website at the same time to submit the data. Considering this architecture..what would be the best way to deploy the WCF so that it could handle multiple users at same time?. I read the article http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and and http://www.codeproject.com/Articles/86007/ways-to-do-WCF-instance-management-Per-call-Per.
I now believe I need to have my WCF service as
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple , InstanceContextMode = InstanceContextMode.PerCall )]
public class Service : IService
{
public bool Method1(data to be saved)
{
}
public List<string> Method2()
{
}
public List<string> Method2()
{
}
}
Am I right ?. Any suggestions ?.
Just answered a similar question yesterday. Based on your description and the picture, I don't see a need to change your architecture. If you're using one of the main WCF bindings (webHttpBinding, wsHttpBinding or BasicHTTPBinding), the service you deploy should easily be able handle dozens of concurrent users, all saving and reading at the same time.
Each client request will generate its own connection and web service objects, each of which can communicate concurrently with your database, whether that request is to read data or write data. When the response is sent back to the client, your WCF service will destroy the objects and clean up the memory for you as long as you're not doing something strange.
I've spent the last two years working on WCF web services on and industrial scale. Lately I've been working on a load testing / benchmarking project that spins up hundreds of concurrent users, each of which is slamming our WCF test server with XML artifacts that get loaded into the database. We've managed to load up to 160 packages (about 110kb - each per client) per second. WCF is not perfect, but it's quick, clean and scales really well.
My experience has been that your database will be your bottleneck, not your WCF web service. If your client wants to scale this archtecture up to an Amazon size web service, then you bring in an F5 load balancer and scale it up that way.
In the project I'm working on, we have several services implemented using WCF. The situation I'm facing is that some of the services need to know when a session ends, so that it can appropriately update the status of that client. Notifying the service when a client gracefully terminates (e.g. the user closes the application) is easy, however, there are cases where the application might crash, or the client machine might restart, in which case the client won't be able to notify the service about its status.
Initially, I was thinking about having a timer on the server side, which is triggered once a client connects, and changes the status of that client to "terminated" after, let's say, 1 minute. Now the client sends its status every 30 seconds to the service, and the service basically restarts its timer on every request from the client, which means it (hopefully) never changes the status of the client as long as the client is alive.
Even though this method is pretty reliable (not fully reliable; what if it takes the client more than 1 minute to send its status?) it's still not the best approach to solving this problem. Note that due to the original design of the system, I cannot implement a duplex service, which would probably make things a lot simpler. So my question is: Is there a way for the sevice to know when the session ends (i.e. the connection times out or the client closes the proxy)? I came accross this question: WCF: How to find out when a session is ending but the link on the answer seems to be broken.
Another thing that I'm worried about is; they way I'm currently creating my channel proxies is implemented like this:
internal static TResult ExecuteAndReturn<TProxy, TResult>(Func<TProxy, TResult> delegateToExecute)
{
string endpointUri = ServiceEndpoints.GetServiceEndpoint(typeof(TProxy));
var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
TResult valueToReturn;
using (ChannelFactory<TProxy> factory = new ChannelFactory<TProxy>(binding,
new EndpointAddress(new Uri(endpointUri),
EndpointIdentity.CreateDnsIdentity(ServiceEndpoints.CertificateName))))
{
TProxy proxy = factory.CreateChannel();
valueToReturn = delegateToExecute(proxy);
}
return valueToReturn;
}
So the channel is closed immediately after the service call is made (since it's in a using block), is that, from a service standpoint, an indication that the session is terminated? If so, should I keep only one instance of each service during application runtime, by using a singleton maybe? I apologize if the questions seem a little vague, I figured there would be plenty of questions like these but wasn't able to find something similar.
Yes, closing the channel terminates the session, but if there is an error of some kind then you are subject to the timeout settings of the service, like this:
<binding name="tcpBinding" receiveTimeout="00:00:10" />
This introduces a ten second timeout if an error occurs.
Check out Managing WCF Session Lifetime with IsInitiating and IsTerminating
I need such scenario: client sends message to server, not waiting for response, and don't care, if message was send properly.
using(host.RemoteService client = new host.RemoteService())
{
client.Open();
cliend.SendMessage("msg");
}
in scenario when firewall is on, or there is no connection to the internet, client dies at "SendMessage". I mean program stops to respond. I wish program don't care about the result. I mean if there is no connection, i wish program to go further, omitting "SendMessage" or sth like that.
What should I do, is there any solution for non blocking method?
Try something like this in your service contract:
[OperationContract(IsOneWay=true)]
void Send(string message);
See the following link:
One Way Operation in WCF
Edit: OP was already using my suggested solution.
Suggested approaches to solve the issue - taken from MSDN (One-Way Services):
Clients Blocking with One-Way Operations
It is important to realize that while some one-way applications return
as soon as the outbound data is written to the network connection, in
several scenarios the implementation of a binding or of a service can
cause a WCF client to block using one-way operations. In WCF client
applications, the WCF client object does not return until the outbound
data has been written to the network connection. This is true for
all message exchange patterns, including one-way operations; this
means that any problem writing the data to the transport prevents the
client from returning. Depending upon the problem, the result could
be an exception or a delay in sending messages to the service.
You can mitigate some of this problem by inserting a buffer between
the client object and the client transport's send operation. For
example, using asynchronous calls or using an in-memory message
queue can enable the client object to return quickly. Both
approaches may increase functionality, but the size of the thread pool
and the message queue still enforce limits.
It is recommended, instead, that you examine the various controls on
the service as well as on the client, and then test your application
scenarios to determine the best configuration on either side. For
example, if the use of sessions is blocking the processing of messages
on your service, you can set the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode
property to PerCall so that each message can be processed by a
different service instance, and set the ConcurrencyMode to
Multiple in order to allow more than one thread to dispatch messages
at a time. Another approach is to increase the read quotas of the
service and client bindings.
Modify your attribute
[OperationContract(IsOneWay=true)]
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;
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.