End a WCF Session from the Server? - wcf

This may be a shot in the dark (I don't know much about the internals of WCF), but here goes...
I'm currently working with a legacy application at a client site and we're experiencing a persistent issue with a WCF service. The application is using the Microsoft Sync Framework 2.0 and syncing through the aforementioned service. The server-side implementation of the service has a lot of custom code in various states of "a mess."
Anyway, we're seeing an error on the client application most of the time and the pattern we're narrowing down centers around different users using the application on the same machine hitting the same service. It seems that the service and the client are getting out of sync in some way on an authentication level.
The error is discussed in an article here, and we're currently investigating the approach of switching from message layer security to transport layer security, which will hopefully solve the problem. However, we may be able to solve it in a less invasive manner if this question makes sense.
In the linked article, one of the suggestions was to forcibly terminate the connection if the specific exception is caught, try again, and if it fails again it wasn't because of this particular theory. Sounds good, and easy to implement. However, I find myself unable to say with confidence if the connection is being properly terminated.
The service operates through a custom interface, which is implemented on the server-side. The only thing that interface can do to end the connection is call EndSession() on the proxy itself, which calls EndSession() on the server which is a custom method.
So...
From a WCF service method, is there a way to properly and gracefully terminate the connection with the client in a way the client will like?
That is, in this custom EndSession() is there some last step I can take to cause the server to completely forget that this connection was open? Because it seems like when another user on the same machine tries to hit the service within the application, that's when it fails with the error in the linked article.
The idea is that, at the client side of things, code which calls EndSession() is followed by nulling out the proxy object, then a factory method is called to supply another one the next time it's needed. So I wonder if something additional needs to happen on the server side (and does by default in WCF were it not for all this custom implementation code) to terminate the connection on that end?
Like I said, a shot in the dark. But maybe in answers/discussions here I can at least further diagnose the problem, so any help is much appreciated. Thanks.

Unfortunately there are only really three ways in which a session can terminated
The client closes the proxy
The service's receiveTimeout is exceeded
before the client sends another
request
the service throws a
non-fault exception which will fault
the channel and so terminate the
session
if you don't want the client involved then you only have 2 and 3 neither of which end well for the client - they will get an exception in both situation on the next attempt to talk to the service.
You could use Duplex messaging and get the service to notify the client that its requires session termination - the client then gets an opportunity to close down the proxy gracefully but this is a cooperative strategy

Related

Lifetime of WCF proxies

During migration of a set of old applications from Remoting to WCF I'm struggling with a good way of lifetime handling for the WCF proxies.
Initially I kept the same pattern I had with Remoting: Create a proxy server object during application startup and use it as long as the application is running.
This pattern had 2 problems, though:
When any call during the runtime of the application failed and the server threw an exception, the client proxy would move to Faulted state and was no longer usable. I fixed this by adding an ErrorHandler on the server side and only throwing FaultExceptions.
With infrequent server calls, the proxy channel would timeout after some time and you only notice when the next call fails. Increasing the Send/ReceiveTimeout to very long timespans is a no-go, from what I read.
This article suggested creating a new proxy for every call and caching the ChannelFactory.
While this solved both problems, it also killed performance.
Caching the ChannelFactory was a good idea, but in contrast to what the article above said, creating the proxy is far from light-weight.
Well, creating the proxy itself is fast, but opening the Channel (what has to be done when calling the server) is incredible slow.
I've been using a plain vanilla net.tcp channel and each server call took about 2 seconds (in contrast to a few ms if re-using the proxy).
Because it's a large code base I don't want to go through each and every server call and check the lifetime requirements for each block of calls.
Now I'm unsure which way to go. Any advice?
Thanks in advance,mav

closing WCF proxy

I have always followed the guidance of try/Close/catch/Abort when it comes to a WCF proxy. I am facing a code base now that creates proxies in MVC controllers and just lets them go out of scope. I'm arguing the case that we need to edit the code base to use try/Close/catch/Abort but there is resistance.
Does anyone know a metric (e.g. perfmon) I can capture to illustrate the problem/benefit. Or a definitive reference that spells out the problem/benefit no one can dispute?
You can create a sample application to mimic the problem. Though I haven't tried you can try this,
Create a simple service and limit the maxConcurrentCalls and maxConcurrentSessions to 5.
Create a client application and in that, call the service method without closing the connection.
Fire up 6 or more clients
See what happens when you open a new connection from a client. Probably the client will wait for certain time and you get some exception.
If the client don't close the connection properly, the connection will still remain open in the service so what happens if 1000s of client connected to the service at a time and leave their connections open? The service has a limitation that it could server 'n' connections at a time and because of that the service can't handle any new requests from clients and that's why closing connections are very important.
I think you are aware about the using problem in WCF service. In my applications I close the WCF connections using an extension method as said in this thread.
Have you tried a simple 'netstat -N' from the command prompt both on server and client? Yoy are likely to see a lot of waiting/pending connections which might exhaust your server resources for no reason.

WCF invalidoperationexception

I encounter this strange problem while using wcf services along with
L2SQL DAL.
The server is hosted at the localhost and contains an implementation of the correspondent interface. The client is familiar with the interface and occasionally queries the database via the exposed service using tcp transport.
When client runs locally everything's just fine.
But whenever client runs at another machine the 'InvalidOperationException' is thrown in the System.Data.dll (the transport still gets delivered) and over the time the channel enters 'Faulted' state(and transport fails to get delivered).
I feel I'm missing something very basic in my application.
Could anyone please point out possible reasons for such and odd behaviour?
An exception in the service will cause the channel to enter a Faulted state, if you do not clean up properly. See: http://bloggingabout.net/blogs/erwyn/archive/2006/12/09/WCF-Service-Proxy-Helper.aspx
for how to clean up the proxy when the service fails.
On your problem with L2SQL, looks like you allready found a solution.

Wcf service waiting for a reply from NServiceBus that will never come

Imagine the following setup: a Silverlight client tunnels a serialized command over the network using a WCF service which in turn deserializes the command and sends it using NServiceBus to a generic host which is responsible for processing the command. The WCF service has - upon sending the command - registered a callback to be invoked. The generic host validates the command and 'returns' an error code (either 0 == success or >0 == failure).
Note: The WCF service is modelled after the built-in WCF service. The difference is that this WCF service receives a 'universal command' (not an IMessage), deserializes it into a real command (which does implement IMessage), and consequently sends the deserialized command off to the bus.
When unexpected exceptions occur, the command gets (after a certain amount of retries) queued in an error queue. At this point, the initiating WCF service sits there idle, unaware of what just happened. At some later point, the Silverlight client will time out according to the WCF client proxy configuration.
Things which are fuzzy in my head:
Does NServiceBus handle this scenario in any way? When does the timeout exception get thrown (if at all)? Or is this something exclusive to sagas?
Presuming I use [OperationContract(AsyncPattern=true)], are there any WCF related timeout settings that will kill the service operation? Or will the EndXXX method be somehow called? Or will it sit there forever, leaking, waiting for something that will never come?
Ways to proceed:
reuse existing timeout mechanisms, provided things don't leak.
build my own timeout mechanism between the wcf service and nservicebus.
notify the wcf service somehow when the command lands in the error queue.
build my own async notifcation mechanism using full blown callback message handler in the WCF service layer.
Things I've done:
run the example provided with NServiceBus.
spiked the happy case.
Any guidance on how to proceed is welcome, be it blog post, mailing list entries, ...
Some motivations for picking my current approach
I'm trying to leverage some of the scalability advantages (using distributor in a later phase) of NServiceBus.
I don't want to host a gazillion WCF services (one for each command), that's why I cooked up a bus-like WCF service.
Even though this is somewhat request/response style, I'm mostly concerned with gracefully handling a command reply not coming through.
You can develop any sort of message type you desire, IMessage is simply a marker interface. If you inspect the WSDL file that the service mex endpoint provides, there is no reference to IMessage, therefore you can define any command you like in you service. That being the case you should be able to use the provided WCF host.
I was able to reproduce the issue you describe using the built-in WCF hosting option. When an exception is thrown, the entire transaction is rolled back and this includes the Bus.Return, and therefore the service never gets a response.
I found a hack around this that I could provide, but I recommend reconsidering how you are using the service. If you are truly looking to do some expensive operations in a separate process then I would recommend in your WCF endpoint that you do a Bus.Send to a different process altogether. This would ensure to your client that the command was successfully received and that work is in progress. From there it would be up to the server to complete the command(some up front validation would help ensure its success). If the command was not completed successfully this should be made known on another channel(some background polling from the client would do).

WCF net.tcp server disconnects - how to handle properly on client side?

I'm stuck with a bit of an annoying problem right now.
I've got a Silverlight 4 application (which runs OOB by default). It uses WCF with net.tcp as means of communicating with the server.
The client uses a central instance of the wcf client proxy. As long as everything keeps running on the server side, everything's fine.
If i kill the server in the middle of everything, i drown in an avalanche of exceptions on the client side (connection lost, channel faulted etc etc).
Now i'm looking for a way to handle this in a clean and centralized way (if centralized is possible).
The SL app has one central client object sitting in App.cs (public static MyClient Client { get;set;}), which gets initialized on application start.
Any idea how to properly handle any connectivity problems on the client object?
You mention that you're using a central instance of the WCF client proxy.
If this is the case, then when a server error occurs, the proxy will go into the Faulted state. To keep things centralized, you could cast the client proxy to an ICommuicationObject and attach an event handler to the Faulted event which replaces the faulted proxy, with a new proxy when the event fires.
The usual warnings about thread-safety for centralized access to resources apply!
I think i found a workable - though not centralized - solution. Instead of cluttering the code with try/catch blocks, all it seems to need is a null-check for the event.Error property. If something happened to the connection, this property is always not null. The exceptions only get raised if you try to access event.Result.
It may not be the most beautiful solution, but it appears to work so far.
Perhaps there is a more elegant way though...