I have a question about WCF service which give the client the ability to mess up with Computer files (copy/paste/delete...etc). service should accept only 1 client at a time, it shouldn't accept a client while another client is already connected, so what configuration does this job?
I'm using NetTcpBinding.
This should do it for you:
http://msdn.microsoft.com/en-us/library/system.servicemodel.description.servicethrottlingbehavior.maxconcurrentcalls.aspx
You need not to do anything as default service behavior is to execute one call at a time. Which means if A is invoking X method and B also want to invoke X method then B request wont be entertain till A request is finished.
But if your are thinking that even after method execution nobody should access the methods then you have to handle this at your own by using Sessions!!
Related
I have a c# application that the client uses wcf to talk to the server. In the background every X seconds the client calls a Ping method to the server (through WCF). The following error has reproduced a couple of times (for different method calls):
System.ServiceModel.ProtocolException: A reply message was received for operation 'MyMethodToServer' with action 'http://tempuri.org/IMyInterface/PingServerResponse'. However, your client code requires action 'http://tempuri.org/IMyInterface/MyMethodToServerResponse'.
MyMethodToServer is not consistent and it falls on different methods.
How can this happen that a request receives a different response?
I think you have a pretty mess problem with async communication, main suggestion (as your question isn't clear very well), is try to identify every request, catch the calls and waiting for them, do asyncronic communication and getting a several work with threading.
As you present it, is a typical architecture problem.
If you present more code, can I suggest some code fixing in my answer and I'll be glad to update my answer.
If this occurs randomly and not you consistently, you might be running in a load-balanced setup, and deployed an update to only one of the servers?
Wild guess: your client uses same connection to do two requests in parallel. So what happens is:
Thread 1 sends request ARequest
Thread 2 sends request BRequest
Server sends reply BReply
Thread 1 receives reply BReply while expecting AReply
If you have request logs on the server, it'll be easy to confirm - you'll likely see two requests coming with short delay from the client host experiencing the issue
I think MaxConcurrentCall and ConcurrencyMode may be relevant here (although I did not touch WCF for a long while)
We have a situation where we need to execute some long running code in the InitializeService method of a Data Service. Currently the first call to the data service fires off the code, but does not receive a response until the long running code has finished. The client is not required to wait for this action to complete. I have attempted to use a new thread to execute the code, however with the code being run we are replacing some files on the server which seems to kill the thread and causes it to bomb out. If I don't have it in a thread it runs fine, but the InitializeService method takes a long time to complete.
Are there any other ways to run this code asynchronously (was thinking maybe there is a way to call another method in the same fashion that a client would)?
Thanks in advance.
All WCF communication is basically Asynchronous. Each call spins up its own thread on the host and the processing starts. The problem you're running into, like many of us, is that the client times out before the host is finished with the work, and there's no easy way around that beyond setting the timeout to some ridiculous amount of time.
It's better to split your processing up into two or more parts, starting the intialization process and finishing the initialization process in separate steps, like this:
One option you could try a duplexed WCF service with a call back function to the client. In other words, client "A" calls the host and starts the initialization routine, but the host immediately sends back the client a value of IntializationStart=True so that the client isn't left waiting for the timeout. Then, when the host has finished compiling the files, it calls the client (which has its own listener) and sends a messages that the initialization is ready. Then the client calls the host and downloads the processed files.
This will works well PC-to-server, or server-to-server.
Another option could work this way: client "A" contacts host and host starts the Initialization routine, again sending back IntializationStarted=True. The host sets an internal (DB) value of FilesReady=False for client "A" until all the files are finished. At that point, host sets its internal value of FilesReady=True. Meanwhile, the client is on a timer, polling the host every minute until it finally receives that FilesReady=True, then it downloads the waiting files.
If you're talking about an iPhone-to-server or Android-to-server, then this is a better route.
You follow?
Can I use Proxy.Open() as an indication to whether the connection should work or not?
I would like to check if a connection is available first, and then, if its not, i won't make any calls to the service during the run of the application.
Note: I only need to check connectivity, not necessarily and entire client-service round-trip.
I Ended up creating a Ping() methods in the service as suggested.
FYI, using simply Open() just didn't work - Open() doesn't raise any exceptions even if the service is offline!
Given the fact that there are so many variables which influence success of a WCF Service call, I tend to add a dummy void KnockKnock()) method to the services to have a real proof if the connection works.
This method can also serve a double purpose: You can call it async to notify the server that he has to be prepared for incoming requests. (Just the initial start-up of the service may take some time.) By invoking the KnockKnock() method the server can start loading the service and give your clients a better initial response performance.
Does anyone know of a way to create a listener for a proxy so that when the CommunicationState has changed I can invoke an action or a method?
An example, I want to update my WCF service for a code change. Since the application is in its early development code changes are very frequent. However, instead of annoying my employees with an email tell them that hey they need to restart their application. I would rather avoid them having to restart the app and having to send them an email. I would rather write a listener that looks at the communication state of a service and if it has changed to a faulted stated then attempt to reconnect.
Edit
Maybe some more context here.
InstanceContext context = new InstanceContext(this);
Subscriber = new SubscriptionService.MySubscriptionServiceClient(context);
Subscriber.Subscribe("");
So basically I want to know when the subscription service has stopped so that I can attempt to reconnect every 60 seconds or so. I tried looking for an event in the Subscriber service but I didn't see anything. Would I need to implement something on the service end?
Thanks
You can use the Faulted event available on the InnerChannel property of your generated client class. The State property of the client class is just a wrapper for InnerChannel.State, so this should work as you desire.
(For reference, you can also use the similarly named event on ChannelFactory<TChannel> if you are creating communication channels in code rather than using generated proxies.)
This question already has answers here:
check the availability of the WCF Web Service
(4 answers)
Closed 8 years ago.
I will have a client application using a proxy to a WCF Service. This client will be a windows form application doing basicHttpBinding to N number of endpoints at an address.
The problem I want to resolve is that when any windows form application going across the internet to get my web server that must have my web server online will need to know that this particular WCF Service is online. I need an example of how this client on a background thread will be able to do a polling of just "WCF Service.., Are You There?" This way our client application can notify clients before they invest a lot of time in building up work client-side to only be frustrated with the WCF Service being offline.
Again I am looking for a simple way to check for WCF Service "Are You There?"
What this obsession with checking whether those services are there??
Just call the service and as any defensive programming course will teach you, be prepared to handle exceptions.
There's really no benefit in constantly sending "are you there?" requests all over the wire...
Even if you could have something like a Ping() method (that just returns a fixed value or something - your service name or whatever) - that only checks whether your service is reachable - what about the database you need to query to get data from? What about other services your service method depends on? It gets quite messy and very very tricky to figure out a way to check all that - just to see if it's there.
In brief: no, there is no reliable and meaningful way to check whether a given service is "there" and "alive" - just call it ! And be prepared to handle a failure - it will fail at times....
There is no value in checking if a service is alive or not. Absolutely none. Why?
if(serviceIsAlive())
{
callService();
}
else
{
handleFailure()
}
Do you see the problem with this snippet? What happens if between the time you check if the service is alive, and the time you call it, the service goes down? This is a race condition, and a bug waiting to happen. So what you need to do, even if you can check the service condition, is:
if(serviceIsAlive())
{
try
{
callService();
}
catch(CommunicationException)
{
handleFailure();
}
}
else
{
handleFailure();
}
But in this block, the handleFailure() call is in two different places - we've got two different paths to handle the same error condition - which seems like a bad thing. So this can be safely reduced to:
try
{
callService();
}
catch(CommunicationException)
{
handleFailure();
}
If your service is hosted in IIS (or WAS), you can perform a resiliency built-in to the IIS6/7 process model. If an worker process fails, another will be started in its place. How it works? Using Ping to analyse. Its called AppoPool Health Monitoring (described here).