0

I have an application that consumes some WCF WebSocket service. Now if host closes connection, I get following exceptions:

  • System.Net.Sockets.SocketException
  • System.Net.WebSockets.WebSocketException
  • System.ServiceModel.CommunicationException

Now I want to handle those exceptions in my client app and try to reconnect/inform a user etc. But how exactly catch those exceptions?

Maybe hook up to channel faulted event. I tried this:

context = new InstanceContext(this);
var endpointAddress = new EndpointAddress(ServerFullAddress);
context.Faulted += Channel_Faulted;    
client = new ServiceName(context, "NetHttpBinding_ServiceName", endpointAddress);

But ChannelFaulted method never gets executed. How to hook up to this event properly, that this method will get executed when websocket is closed.

My other idea is to implement some global exception handler and catch those exceptions there? What do you think?

karollo
  • 573
  • 8
  • 22
  • 1
    See msadn : https://msdn.microsoft.com/en-us/library/ee942778.aspx – jdweng Sep 04 '18 at 12:49
  • I saw that, but I failed to see anything that I can adapt to my scenario. I need to catch those execptions ;p – karollo Sep 04 '18 at 14:08
  • Did you look at the sample c# code? – jdweng Sep 04 '18 at 16:27
  • Yes, it's about handling faults in a SERVICE. I do not have any problems with my service. My problem is that I get exceptions, when service is closing the communication socket – karollo Sep 05 '18 at 06:47
  • A server never starts a connection. So when a client closes the client needs to reconnect. The websocket contains a Listener (see : https://docs.microsoft.com/en-us/dotnet/api/system.net.websockets.httplistenerwebsocketcontext?view=netframework-4.7.2) and as long as the listener is working it will accept a new connection. The only case where you have an issue is if the first connection does fully close. You can only have one connection with the same Source IP, Destination IP, and Port number. So when the first connection does close you cannot reconnect with same IPs and Port number. – jdweng Sep 05 '18 at 07:23
  • I agree. This is my situation, server fully closes a connection ( someone turns it off for example). I get exception on client side and I want to catch it to be able to inform a user about lost connection – karollo Sep 05 '18 at 07:44
  • Your posting said service so I assumed the issue was on the listener side and not the client side. The client error can easily be detected if you are constantly sending data. The TCP transport layer will give an error when the ACK for a message is not returned. When you are not constantly sending then you have to enable the TCP Keep-Alive which sends a zero byte message to determine if the connection is still active. The Keep-Alive gets an ACK from the Server (listener) when the connection is active and doesn't get an ACK which can be detected with an exception. – jdweng Sep 05 '18 at 09:16
  • See following posting : https://stackoverflow.com/questions/36357943/c-sharp-how-to-set-httpclient-keep-alive-to-false – jdweng Sep 05 '18 at 09:17
  • The communication is over websocket protocol. I know exactly when server is down ( i get an exception). My problem is how to catch this exception and proceed with this error. – karollo Sep 05 '18 at 09:45
  • Just try to reconnect using a timer until the connection completes. If it never connects, then you have to check if the connection is closed on both client and server to figure out what need to be done to get connection closed. – jdweng Sep 05 '18 at 10:04

1 Answers1

0

If you control the service, try to sending Faults instead of Exception, this can be simply done with a a few methods,

But I suspect that the reason it doesn't hit the Faulted event is that , your ChannelFactory is not the one that faulted, but rather the clientChannel,

IClientChannel channel = (IClientChannel) Factory.CreateChannel();, you can check the state of the channel object and recreate it using the above method, normally, the OpenedState state is what you are looking for in the channel object, closing, closed, etc would mean either the channel is not open, or it has been aborted or faulted.

mahlatse
  • 1,322
  • 12
  • 24
  • I don't think that I understood you correctly. Yes, I control the service, but I am not throwing those exceptions. They occur when the connection is terminated by the server. And could you tell me why I need to create this channel using factory? I don't get it – karollo Sep 04 '18 at 13:20
  • You cannot connect to the service while the channel is in a created state, it needs to be opened – mahlatse Sep 04 '18 at 13:24
  • check [https://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/ChannelFactory.cs,b8c5b6698ffdd919](https://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/ChannelFactory.cs,b8c5b6698ffdd919) – mahlatse Sep 04 '18 at 13:26
  • I am invoking service's contracts without explicitly opening anything, I checked and my channel is in "Created" state just before calling contract and everything works well. – karollo Sep 04 '18 at 14:04
  • Please check [https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/understanding-state-changes](https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/understanding-state-changes) – mahlatse Sep 04 '18 at 14:14