Closing channel on client side after every call to service application - wcf

I've started working on a client-server distributed application using WCF. The clients should also send requests to the server, therefore I chose to implement duplex operations using the NetTcpBinding since all the clients will b on the same intranet.
On the server side, for the service class that implements the server contract I use these settings
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
Every time a client is initialized, I'm creating an instance of the proxy class generated by adding the service using 'Add service reference' option in Visual Studio. After the proxy is initialized, I send a Connect message to the server:
_proxy.InnerChannel.Faulted += new EventHandler(InnerChannel_Faulted);
_proxy.InnerChannel.Closing += new EventHandler(InnerChannel_Closing);
//send a connect message to the server
_proxy.ClientConnected(ClientHostName, Version, ClientID, ClientIP);
Now the server has a reference to the connected client, by using
OperationContext.Current.GetCallbackChannel<IClientEvents>()
This is pretty straight forward, nothing fancy. However, I'm having a bit of trouble with making the client reconnecting to the server after the server went online. In my scenario, I will have up to 50-100 clients connected to the server and they will rarely communicate with the server, let's say in average, 1 request per hour.
What I want to achieve is to have the client "hanging" while the is offline, for this I try to reinitialize the communication channel on the client side every time the channel ends up in Faulted state, which works ok. But when I try to close the server, I get the following message
This could be because a client failed to close a sessionful channel within the required time.
I'm now struggling to find the most appropriate implementation for my scenario:
Not closing the channel after the service call. This way the client will always try to recreate the channel once the connection with the server is down (e.g. interval of 1 min). Doesn't make much sense to keep the channel opened all this time though, so I'm not that sure about this approach.
Closing the channel after each call and recreate when making a new call to the server. This works fine when making service calls, but what happens if the server wants to send a notification the client? The callback reference on the server side will not be valid anymore, I'd have to wait for the client to send a new connect message to get the new callback reference, right? In this case, should I regularly have a different call similar to a Ping() to the server in order to ensure that the server can always contact the client?
I'm still reading materials on WCF duplex operations, just can't decide which approach is better so that I don't run into problems later on.
Thanks for your advice!

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

Creating a connection to a WCF application

Good time of day. I would like to know how to properly connect in a WCF application. In other words, it should be created when the app is launched and be active throughout the entire operation? Or do you need to create a connection every time a service function is called? Now I have the first option, but somewhere everything is fine, and sometimes for unknown reasons I get an error: it is Impossible to use the object for communication, since it is in the failed state. There are no visible reasons for this - the code runs without errors. NetTcpBinding is used as the binding
The wcf service needs to be hosted in the process so that the client can connect to the server. As long as you are using the wcf service, you need to enable it. Faulted state means there has been an unexpected exception on the server side, so you need to use a try…catch block. Another possibility is that the channel has expired. The default timeout period of the WCF service is 10 minutes. If the client does not communicate with the server within 10 minutes, the channel will be closed. You need to recreate the channel to call the service.

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.

closing WCF proxy

I have always followed the guidance of try/Close/catch/Abort when it comes to a WCF proxy. I am facing a code base now that creates proxies in MVC controllers and just lets them go out of scope. I'm arguing the case that we need to edit the code base to use try/Close/catch/Abort but there is resistance.
Does anyone know a metric (e.g. perfmon) I can capture to illustrate the problem/benefit. Or a definitive reference that spells out the problem/benefit no one can dispute?
You can create a sample application to mimic the problem. Though I haven't tried you can try this,
Create a simple service and limit the maxConcurrentCalls and maxConcurrentSessions to 5.
Create a client application and in that, call the service method without closing the connection.
Fire up 6 or more clients
See what happens when you open a new connection from a client. Probably the client will wait for certain time and you get some exception.
If the client don't close the connection properly, the connection will still remain open in the service so what happens if 1000s of client connected to the service at a time and leave their connections open? The service has a limitation that it could server 'n' connections at a time and because of that the service can't handle any new requests from clients and that's why closing connections are very important.
I think you are aware about the using problem in WCF service. In my applications I close the WCF connections using an extension method as said in this thread.
Have you tried a simple 'netstat -N' from the command prompt both on server and client? Yoy are likely to see a lot of waiting/pending connections which might exhaust your server resources for no reason.

wcf and duplex communication

I have a lot of client programs and one service.
This Client programs communicate with the server with http channel with WCF.
The clients have dynamic IP.
They are online 24h/day.
I need the following:
The server should notify all the clients in 3 min interval. If the client is new (started in the moment), is should notify it immediately.
But because the clients have dynamic IP and they are working 24h/day and sometimes the connection is unstable, is it good idea to use wcf duplex?
What happens when the connection goes down? Will it automatically recover?
Is is good idea to use remote MSMQ for this type of notification ?
Regards,
WCF duplex is very resource hungry and per rule of thumb you should not use more than 10. There is a lot of overhead involved with duplex channels. Also there is not auto-recover.
If you know the interval of 3 minutes and you want the client to get information when it starts why not let the client poll the information from the server?
When the connection goes down the callback will throw an exception and the channel will close.
I am not sure MSMQ will work for you unless each client will create an MSMQ queue for you and you push messages to each one of them. Again with an unreliable connection it will not help. I don't think you can "push" the data if you loose the connection to a client, client goes off-line or changes an IP without notifying your system.