views:

1038

answers:

6

I am trying to log what is happening when the Client gets a time out on a Web Service call.

Take a look at the HelloWorld code below. This is what I wish to do, but it seems IsClientConnected does not work as it allways return true.

[WebMethod]
public string HelloWorld() {
    //.. Do the Webservice stuff
    if (!Context.Response.IsClientConnected) {
        //Log some vital info about this call that timed out...
    }
    return "The WebService Result";
}

Does anyone know another way to check the state of the Web Service call?

When clients disconnect from a webservice call, there are no Exceptions thrown in the Web Service. The code continues to run untill it is done and then returns its result into nothingness (as the connection is closed).

A: 

I would expect each Web Service call to be a request/response. In the event of an error such as the service being unavailable or timeouts I would expect an exception to be thrown.

So is it possible to surround the call with a try catch?

djna
There is no exception thrown inside the web service when the client times out. It just finishes and "sends" the result into nothingness.
Wolf5
aha, so you're talking about the server side, not the client side. Sorry that wasn't clear to me.
djna
A: 

It is better to subscribe to some sort of an event than to check some flag. Basically, ASP.NET is killing the request because it is taking longer than the configured timeout value (executionTimeout setting in httpRuntime element). However, I am not so sure if there is such an event from ASP.NET runtime. Apparently, it does not raise any exceptions either. So there appears to be a disconnect between your service and ASP.NET runtime in this particular case. I would be interested in knowing if there is a way/trick to accomplish what you're after.

In the meantime, you may look into ASP.NET performance counters. There is one called 'Requests Timed Out'. It may include requests that timed out while waiting in a queue or during execution. You can read that performance counter for your web service at the beginning and at the end of your web method. If the number jumped, that means a request just timeout. It may not necessary mean that the jump corresponds to that particular request but in any case you can still log some information such as parameters passed to the web method, elapsed time, etc that might be helpful. You can also increase executionTimeout value in web.config to allow for more time while you're trying to optimize your web method to run quicker if you have clients needing an immediate solution.

If this an asmx web service, you may want to look into Session_End event in global.asax. It may get called when ASP.NET kills the request.

Just some thoughts.

Mehmet Aras
-1: What makes you think the request is "killed"? All he knows is that the client gets a timeout.
John Saunders
What makes you think he is not? May be you should start concentrating more on providing answers than trying find faults with other people's posts. We're trying to give OP some directions and hints. At the end, he needs to decide which one is applicable to or best for his/her problem. We only have limited information to work with and make assumptions against.
Mehmet Aras
"he"? He's assuming that the service will be notified if the client "disconnects". That's not the case. He's also assuming the client disconnects. All of this is being inferred from the fact that the client times out. The fact is, all we know is that the client times out.
John Saunders
Sorry I meant 'the request' not 'he'. What makes you think 'the request is not killed?'
Mehmet Aras
A: 

This will depend upon the details of the Web Service framework you are using. From what you show I would be unsurprised if you there is no mechanism to detect this.

Consider that in general a Web Service need not be even using a transport such as HTTP, you could be responding via queues, or even email. In general you cannot as the server implementation of a simple Web Service be sure that your client has seen the answer. What would you infer if your test did work? At the instant you made the test he's there, a nano-second after you decided not to log, but before you've returned he's gone. There is no transactional relationship between Client and Server in simple SOAP/HTTP.

There are addional Web Service standards to address some of these issues, but usually you neeed to design your Web Services on the assumption that the caller may not see the answer. (perhaps you also provide status services, so a client can drop off and then come back and ask "did you process order "345").

Please tell us what you want to achieve with this logging, maybe somebody has a design approach to help.

djna
Having issues with a service in a cluster, but we do not know which of the cluster services are the one timing out as the clients connect to the cluster URL and not the physical server URL.The goal here is to generally add to my webservices a log-to-the-windows-event in those cases there is a timeout or prematurely disconnect occuring between the client and that server.
Wolf5
I do this assuming the following: When the client does a WS call to the server there is a TCP socket connection established. This connection remains live waiting for the reply. Once the service is done crunching its code, the data is returned on this connection.As long as there is a connection established remaining live as long as the service is doing its code, there should be a way to get the state of that TCP connection.
Wolf5
So I just want a generic "failover" logger for all kinds of web services where the client disconnects that I easily can add into the code.
Wolf5
-1: look at his question. It's obvious he's using an ASMX web service, not WCF.
John Saunders
@Wolf5: TCP/IP doesn't work this way. The server won't know the connection is broken until after it has at least begun sending the response; possibly not until the entire response has been sent and it is waiting for an acknowledgment.
John Saunders
Ok. But if there is a socket I should be able to send back "nothing" and get a result/state from that (according to what I have read)?
Wolf5
@John Saunders. My comment about the general decoupling of web service client and server did not assume any particular platform or web service. It's now clear the objective is some trouble-shooting. However as originally stated it appeared to be about adapting service behaviour upon whether the client is listening. My point is tha such designs are fraught with problems. In that reading of the question is my answer wrong?
djna
@djna: still "wrong" in the sense that it's far _too_ general, given that he's said which platform he's using.
John Saunders
@Wolf5: There is no socket for you to talk to. ASMX web services do not give you access to the wire.
John Saunders
-- damnit :P --
Wolf5
@John Saunders, well if it's a bad idea on all platforms it's a bad idea on a specific one :-). I'll respectfully assert that general principles are valuable ... and try to include something more specific next time.
djna
A: 

HTTP protocol has no specification how server can ping client. The sense of IsClientConnected - to check if exist some 'unsatisfied' query for render HttpResponse. And may be (I'm not sure) if client supports keep-connection-alive.

Think about pulling architecture - were you have one-way method, and some watch-dog from client side to check periodically if method done.

Dewfy
True. This will fail on a poller solution, but so far when I've sniffed network traffic regarding webservices there is a Request and a Response. There was never a new HTTP connection being established to receive the result, as that would show itself in a new HTTP header to the server. So I am assuming there is a connection being kept alive. This connection will be a .Net Socket in some way. Probably hidden, but worst case accessible throu a little reflection. Sockets got a state i can check.
Wolf5
Yes, you are right. IsClientConnected returns exactly what you describe. Keep-alive is just optiomization flag, but not the rule. That is why it talks about possibility(! only) to transfer something else over the same socket.
Dewfy
A: 

I think that in order to get IsClientConnected to return false, the part of your web service code that says "//.. Do the Webservice stuff" would have to take longer to execute than the client's timeout setting. You could probably simulate this by setting the client's timeout to 60 seconds and putting a Thread.Sleep(70000) in your web service code before the IsClientConnected call.

However, I don't think even this would result in IsClientConnected's returning false. Timing out on a web service request and resetting the connection to the server are two different beasts. If Response had a method called IsClientStillWaitingForThisWebServiceCallToReturn, that might do what you want.

I think you could get IsClientConnected to return false if you physically disconnected the client from the network while the web service method was still in the part before the IsClientConnected check, but I'm guessing this isn't what you want.

MusiGenesis
My concept tests is just a webservice app running a sleep as you mentioned and another app calling that webservice with a timeout of 100ms. The app terminates with an error = connection is closed. Then the app comes to the IsClientConnected which then still is True and returns exits with no errors.
Wolf5
As I said, the client timing out on a web service request and the client resetting the connection to the server aren't the same thing, so your result here is exactly what I would expect. IsClientConnected returns True because the client is still connected to the server (even though the web service call has timed out).
MusiGenesis
Timing out on a web service call is something that happens only on the client side, and the server won't know anything about that.
MusiGenesis
Ok. There are 2 things that can bug things here then. The client is still having the connection open in its end, even though its not listening, or the client closes its end (not sending a signal to the server about it). But if the latter the server should still be able to send a "are you alive" call back to the client to check the state on the socket. If that works I can check by trial to see if this is how a client using WS calls and client timing out behaves (disconnect client side).
Wolf5
From what I've just read on this, IsClientConnected only returns false if the user clicks the Stop or Refresh buttons or redirects their broswer to a new server. This means the user's browser actually sends something to the server to tell the server it's not connected any more. My guess is that a client app calling a web service does not send this signal at all when a timeout occurs, so IsClientConnected always returns true. I would also guess that if your client aborted the web service call (as opposed to timing out), IsClientConnected would return False.
MusiGenesis
+1  A: 

I don't believe there will be an exception in general. Even if the service were sending back a long response, such that the outgoing transmission window closed, and timed out waiting to be able to send bytes, all of this would be occurring after the web method had returned back to ASP.NET.

What you should do is learn which web methods are taking too long. You can begin to do this by turning on tracing, as shown in "Enabling Tracing in ASP.NET Web Services". You may then need to go further, and profile the service to see where time is being spent.

You should also look carefully at the event logs. In particular, look for warning events from the "ASP.NET" event source. These come from ASP.NET Health Monitoring. I recommend you get to know the Health Monitoring system, as you may find it does many things for you that you'd have to write yourself, simply at the cost of configuration.

John Saunders
I will look into the Health Monitoring. I am afraid that Tracing will be deadly. There is a LOT of traffic to these services from several different kinds of clients.To bad there does not seem to be a way to detect disconnects between a client and a webservice from the webservice side. If there is, I hope someone will enlighten this thread.
Wolf5
Which OS version are you running? Vista and Server 2008 have an EtwTraceListener that logs to the "Event Tracing for Windows" subsystem, which is fast enough that device drivers use it.
John Saunders
2003 on the servers.
Wolf5
Yeah, that won't have the EtwTraceListener, then.
John Saunders