WCF service maxConcurrentSessions - wcf

I created a WCF service and the user requirement is to have only one client connected on the service at a time.
So I set the value of the parameter maxConcurrentSessions to 1.
It's working great and if another client try to connect after a specific time it receives a timeout exception error.
But I don't like to send the timeout exception error to the client I want to have a more specific error like :
A timeout occurs because the number of maximum client on the service was reached.
Something like that.
It's there a way to do that?
Thanks

You can override default exceptions by implementing IErrorHandler
From MSDN
To explicitly control the behavior of the application when an
exception is thrown, implement the IErrorHandler interface and add it
to the ErrorHandlers property. IErrorHandler enables you to explicitly
control the SOAP fault generated, decide whether to send it back to
the client, and perform associated tasks, such as logging. Error
handlers are called in the order in which they were added to the
ErrorHandlers property.
Implement the ProvideFault method to control the fault message that is
returned to the client
Also check this one .Net WFC/Web service exception handling design pattern

Related

WCF duplex scenario - notifying server of client errors

In a client server WCF duplex scenario, what is the recommended way to let the server know that an error occurred on the client side? Let's say that the server notifies one of the clients that it needs to perform a certain operation and an exception is being thrown on the client side.
On the callback interface, I have something like this
[OperationContract(IsOneWay = true)]
void Work(...);
What's the best approach:
Implement a NotifyServer(int clientId, string message) message that the client can call to let the user know that the requested operation failed,
If I set IsOneWay = false on the operation contract, would I have to call every client on a BackgroundWorker thread in order to keep the UI responsive?
Implementing async operations on the server? How will this work? I can generate async operation on the client, will I have to use the same pattern (BeginWork, EndWork) for the client callback method?
Can't think of anything else, because throwing a FaultException on the client side when IsOneWay = true will not work.
Any advice?
Thank you in advance!
Ad 1. That is one way of doing it... recommended if the Work() may take unpredictable amount of time and you do not want your server thread hanging on that call.
Ad 2. You should always perform WCF operations in the background worker and never inside the UI thread.. If you set IsOneWay=False then obviously Work() method will block on the server until it has finished executing on the remote client and returns results. However even if you set isOneWay=true the method will still block on the low-level WCF communication. If WCF connection is dropped, this can be a long time, before you get notified.
Ad 3.
The pattern is up to you.
Example: MSDN: OperationContractAttribute.AsyncPattern Property
No best solution exists. It all depends on your setup (classes, threads, etc). The WCF layer you code should be easy and convenient to use - that is the main guide line.

WPF Client - Should I make calls to WCF service in background thread?

I have a WPF client that makes calls to 2 WCF services.
One service is for querying only and one service is for commands (CQS pattern).
How should I make the calls to the commands service ?
I read somewhere that all the operations in the command service must be 'One-Way',
because they should not return any values. And that if something went wrong - the operation should throw a 'FaultException' to the client.
But if the commands are all One-Way - what do I do in the client ?
Say I have an 'AddProduct' window in the WPF client, and I enter information and press 'Save'.
I now call 'AddProduct(Product)' in the service, but :
Should it close the window ?
Should it wait for 10 seconds to see if there wasn't any FaultException ?
Should the operation not be 'One-Way' ? If so - should all operations in the command service return some type of generic 'Result' object with 'succeeded' or 'failed' ?
If section 3 is 'Yes' - should I call the service in a seperate thread and 'disable' all the controls on the window until I get a response back from the service ?
Thanks.
I would say option 3 is the way to go, but you probably do not need the generic Result object to communicate errors to the client. As you might know, exceptions are not serialized in the SOAP message so you won't get any of the usual .NET exceptions on the client side. On the other hand, you can still take advantage of SOAP Faults by catching FaultException on the client. Accordingly, if no exceptions were caught on the client, then everything went well.
For more information about fault exceptions and how you can use them to your benefit, take a look at:
Specifying and Handling Faults in Contracts and Services
I think using On-Way is fine but you have to be aware of some one-way call characteristic. If you care and can handle service exceptions then #4 is fine option.
One Way message - Once the client issues the call, WCF generates the request message but no correlated message will be ever returned to the client. Any exceptions thrown on the service side will not make it to the client.
One thing that you should have on is the reliability on your service so side so that you can insure that request has been delivered to the service.
When there is no transport session (basic or wsHttp binding) if exception occurs during the call of one-way operation client will be unaffected and it can continue sending calls on the same proxy instance.
If there is a presence of transport session - service side exception will fault the channel hence client will not be able to re-use proxy for sending more calls. This can give you an option to discover if something went wrong on the server side (but not what went wrong). Although, if service is using a FaultContracts you can still get into situation where client is unaware that something went wrong.
When service throws an exception listed in service side fault contract this will not fault the communication channel hence the client using one-way contract cannot detect communication failure.

callback invalid in wcf service

I have a win forms client that accesses a wcf service for a long running operation. The service exposes subscribe and unsubscribe methods. When a client calls the subscribe method, service generates new guid for it and gets the current callback context, saves this guid and callback context in a client Dictionary and returns the Guid. On user request, client call service with this guid to start the long operation. Once the service finishes the operation it gives a callback to the client. the client then retrieves the processed data from the service.
The error I get sometimes when doing a callback is
The operation 'OnServiceCallback' could not be completed because the sessionful channel timed out waiting to receive a message. To increase the timeout, either set the receiveTimeout property on the binding in your configuration file, or set the ReceiveTimeout property on the Binding directly.
The part that I am not able to understand is that this happens very inconsistently. Most of the times it happens after the client and the service have been running for some time.
I am a beginner in wcf service and welcome any suggestions to solve this error.
Binding has property called receiveTimeout. This property is by default set to 10 minutes. It defines how long does the service instance wait for next request before it is terminated. So if there is no activity between client and service within 10 minutes your service instance is closed and client can't use it any more. In duplex service it can be even more complicated because there are services on both sides. You will probably need to configure receiveTimeout on both ends.
I was able to figure the answer to the error by doing some good old trial and error. The callback was failing because the OperationContext.Current object that I was trying to use was null. This was because I was trying to access the OperationContext.Current object on a thread which was different from the service thread. So to solve that I am now accessing the OperationContext.Current object in the service thread and then passing the callbackContext as a parameter to the external processing logic which actually needs to use it.

How do I properly handle a faulted WCF connection?

In my client program, there is a WCF connection that is opened at startup and supposedly stays connected til shutdown. However, there is a chance that the server closes due to unforeseeable circumstances (imagine someone pulling the cable).
Since the client uses a lot of contract methods in a lot of places, I don't want to add a try/catch on every method call.
I've got 2 ideas for handling this issue:
Create a method that takes a delegate and executes the delegate inside a try/catch and returns an Exception in case of a known exception, or null else. The caller has to deal with nun-null results.
Listen to the Faulted event of the underlying CommunicationObject. But I don't see how I could handle the event except for displaying some error message and shutting down.
Are there some best practices for faulted WCF connection that exist for app lifetime?
If you do have both ends of the wire under your control - both the server and the client are .NET apps - you could think about this approach instead:
put all your service and data contracts into a shared assembly, that both the server and the client will use
create the ChannelFactory<IYourService> at startup time and cache it; since it needs to have access to the service contract, this only works if you can share the actual service contract between server and client. This operation is the expensive part of building the WCF client
ChannelFactory<IYourService> factory = new ChannelFactory<IYourService>();
create the actual communications channel between client and server each time you make a call, based on the ChannelFactory. This is pretty cheap and doesn't cost much time - and you can totally skip any thoughts about having to detect or deal with faulted channels.....
IYourService client = factory.CreateChannel();
client.CallYourServiceMethod();
Otherwise, what you basically need to do is wrap all service calls into a method, which will first check for a channel's faulted state, and if the client proxy is faulted, aborts the current one and re-creates a new one.
I wrote a blog post on exceptions in WCF that deals with how to handle this: http://jamescbender.com/bendersblog/Default.aspx

How to make WCF service using nettcpbinding reconnect automaticlly?

I have an asynchronous WCF service using nettcpbinding. And I send a bunch of requests to it and get result by invoking EndDoWork() in my callback. If EndDonWork throw a exception once, all the invocation after that will throw exception said: communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
I think that's something close the connection because of the first exception. My question is:
1. what decide this behavior? If I use basicHttpBinding, the later invocation of EndDoWork work well. Is it related with keepAlive support?
2. Is there any property of configuration item I can set to ask service reconnect automatically?
The Faulted state of the channel indicates that it cannot be relied on any more. You did not mention what the reason was why the exception was thrown (connectivity, server stopped etc), but as far as WCF is concerned the endpoint is invalid and therefore faulted.
You should recreate the channel and connect to the service again to continue any of your operations. If you use features like Reliable connections then some of the work may be done for you, but if the channel is eventually faulted, the same rules apply.
You will also have to implement your own message queue to re-request messages that were pending when the channel faulted. You cannot rely on the channel to keep and resend the messages.
If I remember correctly, you can avoid the channel faulting if you declare the Fault in the operation contract.
For example:
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract(typeof(MyDefinedFault))]
void Operation();
}
As you have already declared MyDefinedFault in the Operation contract if you throw that from the service, the channel is not going to fault (unless of course you are using the System.ServiceModel.Description.ServiceDebugBehavior.IncludeExceptionDetailInFaults=true that may fault the channel anyways).
Where is the MyDefinedFault class.
how to define this class.