How to detect client's timeout exception on the server side? - c#

I am using synchronous WCF service which works well 99% of the time, but on some very rare occasions client times out before the server finishes processing. Is there a way to detect, on the SERVER side, that the client has timed out? I could use async operation, but in this case server-side timeout detection would save me quite a lot of work. I'm using net.tcp binding, if this matters.

For net.tcp, http, etc. in general no. (see comments above for some ideas; also it might be different for other protocols/bindings/etc.)
The reason is, that the WCF infrastructure code on the server side will not use the channel before it has finished executing the service operation's implementation code and marshalling the response. Only then it will attempt to send the response and at this point recognize that the connection has already been aborted by the client.
When the server gets that error the user code (your service operation implementation) is already done and thus you cannot react to that from there anymore. It might be possible from within a dispatcher, or other extension point, but personally I have not tried. However, that also would not save your server from unnecessary work, because as said, the client disconnect will still only be recognized when the server actually attempts to send the answer.
One "simple" way to mitigate such issues might be to split the work being done into several service operations/calls (if at all possible; and not accidentally introducing server-side state in the process). Or as others have said, have the client implement a "Ping" interface that the server can use to check if the client is still "alive" and the response is still needed.

Related

WCF prevent server disconnect

I have a small client/server application. I was using a hand-coded TCP connection to allow the client to control the server, but now I've converted it to WCF. This saved me a whole bunch of code, but it also gave me a whole new set of problems to fix...
The latest problem is that after a while, the server disconnects the client. I do not want this to ever happen, under any circumstances. Currently the client gets about a quarter of the way through its run, and then explodes with fire because the server has dropped the connection. I need to stop this happening.
I was able to write a trivial WCF client/server pair that replicates the problem. It seems that if the client calls a method, waits 15 minutes, and then calls a second method, the second call throws an exception babbling something about the socket having been closed. If I reduce the delay, everything works fine.
I read in another answer somewhere that setting ReceiveTimeout should fix this. However, when I tried it, this only fixes the problem under .NET; when running under Mono, it still breaks. Since Mono is the actual target platform, this isn't very helpful.
(Think about SSH - you would not want an SSH server to disconnect you just because you didn't type anything for a while. Perhaps you issued a long-running shell command or something... Just because the server hasn't received any data from you doesn't mean nothing is happening! It certainly doesn't mean your connection should get dropped...)
All code is C#. The server is a self-hosting console app. The client is also a console app. All configuration is in code. Binding is NetTcpBinding with default settings.
What can I do to allow the client to run to completion successfully?
I have a few ideas, but none of them are pretty:
Manually send heartbeat messages. (Yuck!)
Detect disconnection and automatically reconnect? (Again, yuck.)
Turn on "reliable mode". (I'm guessing that since the server deliberately ends the session, this won't help.)
Create one connection per method call. (That's going to be quite a lot of code...)
Stop using WCF?
In the end I "fixed" this by having the client make a new connection for every single command. This works acceptably because the client doesn't send commands all that often. It's annoying having to write the connect/disconnect code a dozen times though...

How to solve calls to web services that take too time?

I am developing a Windows RT application that needs to get data from a MVC WebApi server.
The problem is that the response can take from few seconds to 3 minutes.
Which is the best approach to solve it?
For now, I call async to the web api and put a long timeout value to avoid exceptions. Is it a good way? I do not like too much because the server have a open connection opened all time. Can it affect significantly to the server performance?
Is there some thing like "callback" but for web services? I mean that the server calls to the client to send the data.
Yes, there are ways to get server to callback client, for example WCF duplex communication. However, such techniques will usually keep the connection open (in most cases this is TCP session). Most web servers do not support numerous concurrent requests and thus each prolonged call to the server will increment the number of concurrently connected clients. This will lead to heavy resource utilisation at the point where it shouldn't be. If you have many clients, such architecture is bound to fail.
REST requests shall be lightweight, small and fast. Consider using a database to store temporary results and worker servers, to process the load. This is a server-side problem, not client-side.
Finally I solved it using WebSockets (thanks oleksii). It keeps the connection open but I avoid to poll for the result repeatedly. Now, when the server finishes the process, sends the data directly to the client. WebSockets is a protocol that relays over TCP and has been standardized.
http://en.wikipedia.org/wiki/WebSocket

how to use netMsmqbinding - with server connected scenario

This might look a question where you can read the answer on MSDN, but I still want to ask about the scenario, as I want to solve the business problem.
I have a service hosted on a server, and a client makes service calls. It currently uses netTCP binding. Everything works fine when the service is available, when the server is up and running. Now, I need to handle the server down scenario. I use the local cache file on the client to serve the client requests in case of server down scenario. Now I want to cache all the requests made while server down and want to make service calls once server is up and running.
I am thinking about using the netMsmqBinding, because all I've read suggests that it works well in the disconnected scenario.
Q.1 Can I use the netMsmq to handle this scenario?
Q.2 If not then what could be another approach with which I can follow to solve this problem?
Q.3 Can I use WS-Discovery in case of server down to find that the client calls won't be able to contact the service?
EDIT : The scenario is Client-Server. But i do need to give response on every call to the client. The client is also developed and maintained by me only so i am in a good position to implement the best suitable solution.
Please guide me as I'm not too good with WCF.
Yes, you can use netMsmqBinding for this purpose. We are doing that for services running over a satellite link that can be down often.
One important limitation you need to take into account is that all calls must be one way, being a queue-based transport. If you need to get the results of a request, you'll have to provide a separate response mechanism (it can be a similar queue in the opposite direction)
Ad question 1: using MSMQ is excellent for a scenario where the service may not always be up and running. Note that the server that hosts the message queue must be up and reachable to receive the messages. However, you haven't told us anything else about your scenario, particularly why you currently have NetTCP. The reason that's important, is because there are some things you can not do with MSMQ, for example duplex communication won't work out of the box.
Ad question 2: an alternative may be to implement logic in the client (it's unclear from the question if you're the owner of the client software) to have a local queue and retry messages later if a service is (temporarily) offline. I guess you may even have a proxy MSMQ service on the client, relaying the messages to the main service once it's up.
Ad question 3: yes, you can use Discovery for this. The service will have to announce to the clients when it goes online or offline. The simplest example is using the UdpAnnouncementEndpoint. In the clients you can use the AnnouncementService class to listen to the service coming online or offline, and keep a local list of available services. Alternatively (for example when UDP broadcasts aren't feasible) you can create a discovery proxy service at a well known location that listens to announcements, which the clients can access for instant-knowledge on whether the service they need is online

Permanent TCP connection or connection etablishment at request processing

I am developing a TCP server, which shall communicate with the client, if specified tasks are finished. So I open on the server a socket and the client connects on it.
That connection can be used for data tranfers back to the client, too. That is quite okay.
But what about connection aborts and anything like that?
My thought was to connect each time to the server, when the client have to communicate with it. But how can I send data back to the client?
Shall I open a socket on the client side, too?
EDIT:
I have considered WCF, too. I think it could be a very good way to implements server client hierarchy.
What do you think?
It depends on the rest of your requirements. If we're talking a message that is in no rush that might be sent once a day, the right solution might be for the client to connect to the server periodically and check if there are any messages. If we're talking something that's more common and more in a rush, the right solution might be for the client to keep a connection open to the server at all times. In some cases, the right solution might be for the server to make a 'backwards' connection to the client, if possible -- perhaps with an option to fall back to a persistent connection from the client to the server if the 'backwards' connection isn't possible.
See this article on Push technology, particularly the section on long polling.
From a runtime POV having the server connect to the client needs a network environment supporting this (firewall/IDS etc.).
IF you can't be sure that this is always the case then this option is ruled out IMO.
As for the client keeping the connection open:
I think this is a good option... you need to make sure that the client implementation detects any connection problems and automatically reconnects...
Whatever solution you implement you might need to implement a queue of events per client... depending on your requeirements these queues might even need to be persistent...
WCF can work in all the ways I described and offers several things (like serialization, optional session management, transport security etc.) which help build a robust and well-maintainable system... although a pure TCP/IP-based solution might be better performance-wise...

Finding the time taken to send messages with WCF net.tcp

I’m writing a prototype WCF enabled distributed app, to try and find out any issues I’ll have upgrading my existing “sending xml over tcp to communicate” apps I’ve got. I’m using Callback Contracts to register clients with a server (Singleton in ServiceHost) and so far all the communications between client and server work. I can connect multiple clients to the server and send a broadcast from the server that is received by all clients. I can block a particular client and the other clients still receive the calls. This is good.
To continue my learning and evaluation of performance I would like the client to record what time the server sends each message, as well as what time the client receives that same message. How should I best go about this?
Is there something similar to SOAP extensions, where I can add to the outgoing from the server and incoming to the client? Or would I need to add a “timeSent” parameter to every method that the server calls on the client and record the time received on the client (yuck!)? Is there a better way to accomplish this?
I am using net.tcp rather than wsDualHttpBinding (which also works but is less performant).
Hmmm... that's a difficult one. The problem here is you can't even make sure both the client and the server timers are in sync.
If what you want to do is send some out-of-band data, so that you don't need to modify your methods, you can use the method suggested here. I think it should be enough.
David is right about the problems with clock synchronization. However, adding the timestamp information outside of the service/client implementation is not hard at all on WCF.
You're right it doesn't support SoapExtensions, though, in fact, it has a much richer set of extensibility point. In your specific case, I think a custom behavior that adds a MessageInspector would probably work.
There are actually two message inspector interfaces: One for the client (IClientMessageInspector), and one for the server (IDispatchMessageInspector).
The easiest way to hook up a dispatch inspector on the service side is through a service behavior (IServiceBehavior), since you can hook that up to your service implementation as a custom attribute. Here's a simple example of how to do it. You can also hook it up through an IEndpointBehavior, but you need to do that either through code when setting up the service host or through configuration, which requires writing a bit more code.
On the client side, you still use an endpoint behavior, but introducing those through code is a lot easier since you have direct access to the ClientRuntime from the proxy client.
Anyway, I would think that something like a timestamp is better added to the message as a custom header so that it is not part directly of the message payload.

Categories