Creating a connection to a WCF application - wcf

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.

Related

Closing channel on client side after every call to service application

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!

How to recover from a comms/service failure with WCF netTcpBinding?

I'm developing a client/server app in which the client calls the WCF service every few seconds. I'm not using IIS - the service runs as a console app (with the intention of installing it as a Windows service on production systems).
I started off using basicHttpBinding, and if I stop the service (to simulate a comms/server failure) the client simply ignores the fact that it can't connect to the service, by handling the EndpointNotFoundException that gets thrown. After restarting the service, the client is able to start calling it again and everything is good.
I've now switched to using netTcpBinding, and this time when I stop the service it takes a little while for its console window to close (presumably due to the way TCP manages the connection, which eventually times out). At this point the client gets a CommunicationException ("the socket connection was aborted"). When I restart the service, the client isn't able to "resume" like it did with basicHttpBinding. Each time it tries to call the service it throws a CommunicationObjectFaultedException ("The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.").
How would I go about building in some kind of resume/recovery behaviour, similar to what I saw with basicHttpBinding?
You cannot reuse the channel as it has faulted. You should cast your client to an ICommunicationObject and call Abort() to clean up.
After that you simply start afresh by creating a new client channel. You may want to do this on a timer if your server is down for a period of time.

End a WCF Session from the Server?

This may be a shot in the dark (I don't know much about the internals of WCF), but here goes...
I'm currently working with a legacy application at a client site and we're experiencing a persistent issue with a WCF service. The application is using the Microsoft Sync Framework 2.0 and syncing through the aforementioned service. The server-side implementation of the service has a lot of custom code in various states of "a mess."
Anyway, we're seeing an error on the client application most of the time and the pattern we're narrowing down centers around different users using the application on the same machine hitting the same service. It seems that the service and the client are getting out of sync in some way on an authentication level.
The error is discussed in an article here, and we're currently investigating the approach of switching from message layer security to transport layer security, which will hopefully solve the problem. However, we may be able to solve it in a less invasive manner if this question makes sense.
In the linked article, one of the suggestions was to forcibly terminate the connection if the specific exception is caught, try again, and if it fails again it wasn't because of this particular theory. Sounds good, and easy to implement. However, I find myself unable to say with confidence if the connection is being properly terminated.
The service operates through a custom interface, which is implemented on the server-side. The only thing that interface can do to end the connection is call EndSession() on the proxy itself, which calls EndSession() on the server which is a custom method.
So...
From a WCF service method, is there a way to properly and gracefully terminate the connection with the client in a way the client will like?
That is, in this custom EndSession() is there some last step I can take to cause the server to completely forget that this connection was open? Because it seems like when another user on the same machine tries to hit the service within the application, that's when it fails with the error in the linked article.
The idea is that, at the client side of things, code which calls EndSession() is followed by nulling out the proxy object, then a factory method is called to supply another one the next time it's needed. So I wonder if something additional needs to happen on the server side (and does by default in WCF were it not for all this custom implementation code) to terminate the connection on that end?
Like I said, a shot in the dark. But maybe in answers/discussions here I can at least further diagnose the problem, so any help is much appreciated. Thanks.
Unfortunately there are only really three ways in which a session can terminated
The client closes the proxy
The service's receiveTimeout is exceeded
before the client sends another
request
the service throws a
non-fault exception which will fault
the channel and so terminate the
session
if you don't want the client involved then you only have 2 and 3 neither of which end well for the client - they will get an exception in both situation on the next attempt to talk to the service.
You could use Duplex messaging and get the service to notify the client that its requires session termination - the client then gets an opportunity to close down the proxy gracefully but this is a cooperative strategy

Windows service connecting to other service over wcf crashes

I have two windows services. One ('server') acts as a WCF host to which the other ('client') connects. So I have configured a dependency from client to server. Both are also set up to start automatically.
When I start these services by hand, everything works fine. When I stop both services and tell client to start, then server will be started before client and all is fine.
However, when I reboot the machine only server is started.
When I add a diagnostic listener I see it got a TimeoutException with the helpful message:
The HTTP request to 'http://[server address]' has exceeded the allotted timeout of 00:00:00. The time allotted to this operation may have been a portion of a longer timeout.
At some other SO question there was an answer that claims WCF is probably confused about what went wrong and therefore starts lying about the timeout.
Did I perhaps miss a dependency for either service? Does WCF require something that hasn't or is being started when client is trying to contact server?
I think you should check your client service. On startup windows services are starting while network devices are still being initialized. Services should be ready to start without network and without any network device. Usual approach is to keep periodic retries to establish connection. You can do little experiment on your machine by uninstalling all network adapters and trying to start up your services.
Additional quick workaround you can do is to setup recovery options on your service -- for example you can configure it to restart service on crash after some timeout -- you can do this through UI in services.msc or in command line using 'sc config' command.
Configuring the dependency between the two Windows Services is not necessarily sufficient to avoid there being a race condition: i.e. to avoid the client service calling the WCF service before the server's WCF channel stack is fully initialised.
The service dependency just ensures that the Windows Service Control Manager won't start the client service process before the server Windows Service has notified the SCM that it has started. Whether this is sufficient depends on how you write the server.
If the server service starts a new thread on which to initialize the WCF stack, your OnStart method is probably returning before the WCF stack is ready for clients. There is then a race condition as to whether the client's first call will succeed.
On the other hand, if the server service does not return from OnStart (and thus doesn't notify the SCM that it has started) until the channel stack is fully open, the dependency removes the race condition, but there is a different pitfall: you need to beware that the SCM's own timeout for starting the Windows service is not triggered while waiting for the WCF stack to initialise, as might well happen on a reboot if the WCF service depends on the network stack, for example. If the server's OnStart does not return within the SCM's timeout, the SCM will not try to start the dependent client service at all, because it does not receive the server's start notification. (There will be a message in the Windows event log from the SCM saying that the server service didn't start within the expected time.) You can extend the SCM timeout by calling ServiceBase.RequestAdditionalTime while the WCF service is being initialised.
Either way, the client service really ought to be written so that it doesn't fail completely if the first WCF call doesn't succeed.
You don't actually say what binding you are using. If client and server services are always running on the same machine, as you seem to indicate, then consider using the NetNamedPipeBinding: then your service won't be dependent on initialization of networking resources and startup should be quicker.

WCF Service polling hangs

I have 2 wcf services, 1 which polls the other service at regular interval.The service2 is hosted in no. of machines with the same configuration.
My problem is that whenever the poller service gets restarted, even though the service2 on other machines runs fine, i am not getting the response from those services (basically it gets timed out - getting SYSTEM.TimeOutException ). If I try to access the same service (service2) from some temp application (without restarting the service2) it gives response.
If I restart the service2, than it works fine, the service1 (poller service) gets the responses from all hosted services (Service2).
Dont know what is causing problem.
Regards,
Chirag
Attach VS to your wcf service which hangs. And find out if your connection is successful.
Do it with both services, so that you can debug the services at runtime.
If you're using a sessionful binding (netTcpBinding, wsHttpBinding), it's more than likely that you're not explicitly closing your client channel when you're done with it. This would cause the behavior you see, because the session takes a minute or so to time out if you don't explicitly close it, and the default max number of sessions is low (10)- the server will let new sessions stack up until old ones close. You can also adjust the service throttle on the server side binding to increase the max number of open sessions allowed, but you really should make sure your clients are getting cleaned up properly first.