Oyatel / CometD.NET

CometD.NET is a C# client library for the Bayeux protocol
43 stars 34 forks source link

Catching System.Net.WebException Exceptions?? #17

Open naikvi opened 12 years ago

naikvi commented 12 years ago

Hi Sir,

I am implementing the Bayeux Protocol via your library in situations where I have a failover implementation on the server side but I have a single virtual IP address I interact with. Therefore, when the server fails over I encounter a TCP reset and after that I need to renegotiate the connection. However, from my client side, I don't receive anything indicating that the TCP reset occurred. When I look at the debug output I see that your library encountered the System.Net.WebException and this would be useful for my client to be notified of. How do I get access to this exception or at least get an error notification in my client when using this protocol to know that I should re-negotiate the handshake and subscription? Is it possible to get access to this exception or get an error reported back to me for it?

Thank you.

grEvenX commented 12 years ago

Hi, it's been a while since I've been deep into the source, but if I remember correctly an exception of this type should make the library automatically reconnect and re-subscribe any subscription. Have you tested that it doesn't work out of the box?

naikvi commented 12 years ago

You might be right about that because I see the exception reported in the output window of Visual Studio (in debug mode) about 3 to 4 times before it quits. My thinking is that perhaps the re-try is occurring too quickly as my server side takes a while (maybe a good 10 seconds) to bring the virtual IP down on one box and back up on the other (through a failover). I am not sure if this can be verified by the output but I can paste it in here:

A first chance exception of type 'System.Net.WebException' occurred in System.dll System.Net.WebException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at Cometd.Client.Transport.LongPollingTransport.GetResponseCallback(IAsyncResult asynchronousResult) in C:\Users\naikv\Desktop\Oyatel-CometD.NET-0fcf58c\cometd\client\transport\LongPollingTransport.cs:line 240 A first chance exception of type 'System.Net.WebException' occurred in System.dll System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state) at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.TlsStream.CallProcessAuthentication(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) at System.Net.TlsStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback asyncCallback, Object asyncState) at System.Net.TlsStream.UnsafeBeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback asyncCallback, Object asyncState) at System.Net.PooledStream.UnsafeBeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) at System.Net.ConnectStream.WriteHeaders(Boolean async) --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at Cometd.Client.Transport.LongPollingTransport.GetResponseCallback(IAsyncResult asynchronousResult) in C:\Users\naikv\Desktop\Oyatel-CometD.NET-0fcf58c\cometd\client\transport\LongPollingTransport.cs:line 240 A first chance exception of type 'System.Net.WebException' occurred in System.dll System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.BeginSend(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, AsyncCallback callback, Object state) at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.TlsStream.CallProcessAuthentication(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result) at System.Net.TlsStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback asyncCallback, Object asyncState) at System.Net.TlsStream.UnsafeBeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback asyncCallback, Object asyncState) at System.Net.PooledStream.UnsafeBeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state) at System.Net.ConnectStream.WriteHeaders(Boolean async) --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at Cometd.Client.Transport.LongPollingTransport.GetResponseCallback(IAsyncResult asynchronousResult) in C:\Users\naikv\Desktop\Oyatel-CometD.NET-0fcf58c\cometd\client\transport\LongPollingTransport.cs:line 240

Can you tell by the output above if you are reattempting the subscription?

Thank you very much for responding back. By the way, I posted an earlier question asking if it works under HTTPS and it definitely does as I was able to get it working and am using it for this example.

naikvi commented 11 years ago

Hi Sir,

I made progress on this when I used the Java cometd library (at http://cometd.org/documentation/cometd-java/client). I decided to have my application monitor to see if client.isConnected() became ever false through a separate thread and if so, I know (or assume) that I lose TCP connection and/or cometd subscription connection and then I simply reissue the connection and I can get events again.

However, in your C# library, when I check for the flag form.client.Connected I find that every so often it becomes false even though I haven't lost connection. This makes me think that this doesn't represent a connection lost but instead represents a general longpoll timeout. Therefore, I am still unable to use this logic efficiently. I still see that a loss of connection does also occur when I get a TCP connection loss BUT what ends up happening is that the library ends up connecting/disconnecting/reconnecting too many times. Is there another flag that can tell me if the connection is lost?

Thank you sir.

arvydas commented 11 years ago

I'm also experiencing the same issue with Rails faye server.