Socket connection was aborted - WCF - wcf

I have a simple client server apps that uses WCF (netTcpBinding) when i'm launching the server and sending messages through the client everythings works fine , but when i'm closing the server manually and open it again (without closing the client app at all) the next time the client tries to send a message to the server i get this exception (on the client side):
The socket connection was aborted. This could be caused by an error processing y
our message or a receive timeout being exceeded by the remote host, or an underl
ying network resource issue. Local socket timeout was '00:00:59.9843903'.
if i use basicHttpBinding the problem doesn't occur.
is any one knows why this problem occurs ???
Thanks,
Liran

This is expected behavior. When you close the server, TCP connection on the server is closed and you can't call it from the client anymore. Starting the server again will not help. You have to catch the exception on the client, Abort current proxy and create and open new one.
With BasicHttpBinding it works because NetTcpBinding uses single channel for whole life of the proxy (the cannel is bound to TCP connection) whereas BasicHttpBinding creates new one for each call (it reuses existing HTTP connection or create new one if connection doesn't exist).

Related

Questions about SignalR Connection

All,
I am using SignalR (.net 6) and have couple of questions about SignalR Connections (specifically SignalR connections that use web sockets):
Q #1)
If the SignalR client crashes, will SignalR server dispose the underlying connection automatically for me (and the OnDisconnectedAsync() event will be fired)?
The idea is to dispose client resources (on the server, resource ex: NHibernate session) that are tied to each connection.
My Tests Indicate (on local machine, both server and client):
I tried to simulate this scenario where I had a running client which then I shut down with Task manager and the minute Windows released resources for the process, the SignalR server somehow detected that connection was lost and released the connection and OnDisconnectedAsync() was called. I am not sure if my test was sufficient for this use case (client crash). I am curious of how did the server know, was it the fact the maybe the finalizer for client connection ran?
Q #2) If the current connection between client and server is broken or interrupted and SignalR needs to reconnect, and it successfully reconnects, does it use the same connection (with the same connection ID/same web socket) or does it attempt create new connection (tied to a new web socket)?
https://learn.microsoft.com/en-us/aspnet/core/signalr/configuration?view=aspnetcore-6.0&tabs=dotnet
The server considers the client disconnected if it hasn't received a message (including keep-alive) in this interval. It could take longer than this timeout interval for the client to be marked disconnected due to how this is implemented. The recommended value is double the KeepAliveInterval value.
It assigns a new connection id. Consider using other data to track which user is it, eg. Checking in the on connect and on disconnect methods.
https://learn.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-6.0

WCF client becomes unusuable after internet is lost and reconnected

On this previous question: Tell when wcf client lost connection One of the commenters states:
Your service should not care whether a network cable was disconnected.
One feature of TCP is that unless someone is actively sending data, it
can tolerate momentary interruptions in network connectivity.
This is even more true in WCF, where there are layers of extra
framework to help protect you against network unreliability.
I'm having an issue where this is not working correctly. I have WCF client that makes a connection to the server using a DuplexChannelFactory. The connection stays open for 3 minutes. I disconnect the client from the internet and reconnect. The client regains internet connection, however any calls made from the server to that client fail. Once the client reconnects it begins working again.
When I pull the plug on the internet, the client throws several exceptions but the channel is still listed as being in an open state. Once the connection is regained and I made a request from the server to the client, I get errors such as: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.
Obviously if the request comes in when the client is offline it won't work, but I'm trying to get it so this channel will recover once the internet comes back without having to set up a new connection.
Should this be working as-is, based on the comment I listed above? Or is there something I need to change to make that actually work?
The issue here is that the channel you're trying to use is in a faulted state, and cannot be used any longer (as the error message indicates).
Your client needs to trap (catch) that exception, and then abort the current channel and create a new one. WCF will not do that for you automatically, you have to code for it yourself.
You could also check the CommunicationState of the channel to see if it is faulted, and recover that way.
A final option would be to use the OnFaulted event handler, and when the channel is faulted, abort the channel and create a new one.

WCF Client Windows Service - How to handle connection errors?

I have a Windows Service running on a client machine which communicates to our server using WCF. The basic process is this:
Every 3 minutes, the client makes a connection to the server using a DuplexChannelFactory (CreateChannel).
While this connection is open, the server sends messages to the client.
The connection must remain open constantly because the server may need to communicate with the client at any time. This is why we are refreshing the connection every few minutes.
For the most part this system works fine. However if the client has a spotty Internet connection, the channel becomes aborted. Here's what happens in this case:
The client opens a connection. This connection stays open for 3 minutes until it is closed and re-opened.
During the first connection, the computer loses Internet connection for a few seconds.
The Windows Service running on the client throws a System.Net.Sockets.SocketException and System.ServiceModel.CommunicationException. The code currently does not catch these exceptions.
The computer regains Internet connection.
The server tries to communicate with the client (still during the first 3 minutes).
Since the first connection is still open, the server cannot communicate and gets the following error: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted.
I'm trying to figure out how I can catch the errors that happen in step 3 so that I can close the current connection and re-open it. I currently have a function to handle the Faulted event, but this event is not hit when the connection is lost. I've tried looking into global error handling but it seems like most of the tutorials are for the server side, not client. Also, since the connection is just staying open indefinitely, there is nowhere I can put a try/catch block since there is no code that is actually running at the time it happens.
I was able to accomplish catching these exceptions by using the FirstChanceException event handler. I had to use this event because the exceptions were being handled automatically deeper down so I couldn't catch them.
In the Windows Service's OnStart function:
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.FirstChanceException, AddressOf HandleException
And the function I wrote checks if the exception is of a certain type I know the connection has failed and I create a new connection.

WCF call fails because underlying connection was closed

I'm making a call to a WCF service but I get a CommunicationException on the client while receiving the response from the service.
System.ServiceModel.CommunicationException: An error occurred while receiving the HTTP response to http://localhost:8080/Service. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from 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
The client that makes the call is a WCF proxy client.
The service method executes without
any exceptions.
The WCF call works fine in those cases where it does not
take a long time for the serivce
method to finish.
The WCF call fails with the above exception message when the service method is taking long time to finish.
The sendTimeout property of the client's binding has been increased to 30 minutes to accommodate the time it can take for the service method to finish.
Try to set the receiveTimeout equal or greater than the time it takes for the service method to complete. The default value for the receiveTimeout property is 10 minutes. So if the service method takes longer time to complete the connection will be closed (if no other activity takes place before the receiveTimeoutoccurs). The receiveTimeout property is described here.
A very long operation like this should most likely be called asynchronously - in other words, the client asks the server to prepare the data, then gets on with something else while the server does the work. When the server's finished it calls the client back.
Asynchronous WCF operations are discussed here.

WCF Server/Client connection handling

I'm having some problems with my WCF server and client connections.
If I use my service and client normally, meaning my client connects and disconnects thru normal operations (myclient.Close()) everything works fine. But in the instance that I have the server running and I use the visual studio "Stop" button to exit my client application, my server and client communications seems to mess up and the server doesn't clean up the connection correctly and any new connections from my client are very unstable and only certain function calls work until one function will throw an exception of:
System.ServiceModel.CommunicationException: An error occurred while receiving the HTTP response to http://localhost:8080/Design_Time_Addresses/Service_Beta1/Service. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive.
And many other exceptions after that, and I'll spare you from reading those.
If I shutdown the server and client and restart both, all my calls work fine until I do the drastic "Stop" in visual studio. How can I force the server to clean up improperly closed connections? I know in production the "Stop" button is gone and in theory there shouldn't be problems, but I don't want to have server connection problems from crashes of clients or bad disconnects. Because inevitably there will be those cases. It's best to fix this now before you have 20+ clients trying to connect and getting exceptions.
Thanks
Sorry for taking such a long time to post a reply. My problem is I was passing back a datatable to the client but wasn't giving the table a name on creation. See below.
Dim dt As New DataTable() 'Passing just a blank un-named table to client gave errors.
Dim dt As New DataTable("Table") 'Naming the table like so passes just fine.