TChannel state change events? - c#

hopefully a simple WCF beginners question..
I have a WCF channel factory, returning a service proxy TChannel:
// setup connection to server
var endpointAddress = new EndpointAddress(GetAppSetting("Endpoint"));
var tcpBinding = new NetTcpBinding();
channelFactory = new DuplexChannelFactory<IExcelServer>(this, tcpBinding, endpointAddress);
server = channelFactory.CreateChannel();
I would like to know when this service proxy changes state (Faulted, Closed etc). I can see events on the ChannelFactory itself, however I'm not sure this is the same as the channel itself, and even here stopping the server process doesn't cause a state transition.
This is a CallbackContract service, and in almost all interactions the server is sending data to the client. Therefore I can't simply rely on catching the failure when I make a server call from the client.
Should I send a heartbeat from client to server to trigger the state change?

The instance you get back from CreateChannel implements TChannel but also IClientChannel which has state changed events like Closed, Closing, Opened, etc.:
server = channelFactory.CreateChannel();
((IClientChannel)server).Faulted += FaultedHandler;
P.S: As you pointed out, the states of the channel and channel factory are related but not the same. If a Channel is faulted it doesn't necessarily mean that the ChannelFactory is.

Related

Disposing faulted service channels on client side in WCF

I have a WCF Websocket client server communication. What I want to do on client side, is to keep trying to reconnect to the server, if server was shut down or something. From what I know, once a server is shut down, channel is in faulted state so I cannot use it again. I need to create a new one, but I am afraid, that there is memory leak in my solution:
creating the websocket service:
InstanceContext context = new InstanceContext(this);
ServiceReference.SomeServiceClient client = new ServiceReference.MLogDbServiceClient(context);
reconnecting:
client.Abort();
client = new ServiceReference.MLogDbServiceClient(context);
In Windows Task Manager I saw that in two minutes my app grew from 29mb to 48mb while I was keeping to create new channel every 20ms ( it was just for memory leak test purposes ). Anyone has a leak-free solution for me?
My client application NEEDS to keep reconnecting to the server (not so frequently but still). Greetings

Resuming a WCF duplex connection from the client

I have a client that connects to a server which can potentially go down and come back up a few times a day. So far at the clients I'm using the following method to check for a faulted connection, the on faulted handler re-establishes a connection back to the server:
ICommunicationObject communicationObject = this as ICommunicationObject;
communicationObject.Faulted +=
new EventHandler((sender, e) => { OnFaulted(sender, e); });
Can anyone advise on the best possible (best practice) way to maintain a persistent duplex connection from the client side?
Extra Info:
With the above code where 'this' is the client connection inheriting from DuplexClientBase the handler is not triggered if the server is simply shutdown (application.exit), is there a better way to handle this?

WCF Service best practice to keep my services alive

I have several WCF Services in my WPF application, I open them using this method:
private void StartSpecificWCFService(IService service, string url, Type serviceInterfaceType)
{
ServiceHost serviceHost = new ServiceHost(service, address);
serviceHost.AddServiceEndpoint(serviceInterfaceType, new NetNamedPipeBinding(), url);
serviceHost.Open();
//sign to serviceHost.Faulted ??
_wcfServicesHolder.Add(serviceHost); //A dictionary containing all my services
}
the services attributes are:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
The services are logging service and event service, they get many calls from other processes.. I use namedpipes since it is the fastest and the processes run on SAME computer.
My question is - How do i maintain these services to be up all time ?
Poll timer that iterate _wcfServicesHolder and check if service is opened
sign to serviceHost.Faulted event.
And after a service is in faulted state, does the client (on different process) must be re-created ? or it can still broadcast message on same channel ?
The exception i receive is:
There was no endpoint listening at net.pipe://localhost/LoggingService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
Why do the services have InstanceContextMode = InstanceContextMode.Single with concurrent thread access? Do the services hold some kind of in-memory thread-safe state? If not, it may be well worth trying to re-factor the services to use InstanceContextMode.PerCall. This should be your default and preferred choice when configuring WCF services - WCF is primarily a technology for implementing a service-orientated architecture, and using a mode other than PerCall violates the Statelessness principle of SO Design Principles.
In support of this, if you have a server-side fault with InstanceContextMode.Single, this suggests something has gone seriously wrong in the service. Any state that you maintained within the service will be lost - clients can not expect just to re-connect and resume as normal.
Whatever InstanceContextMode you end up using, your channel will fault if it remains open with no clients connecting to it for a certain length of time. Over TCP (or any protocol that explicitly exposes a reliable session), you can specify the inactivity timeout on the reliable session, but you have no such option using pipes.
With pipes, leaving a channel open longer than the configured timeout, will fault the channel rendering it useless. You can subscribe to the channel faulted event, and recreate the proxy if you are interested in keeping a channel open to the service for the lifetime of your application. As you suggest - another option is to keep polling along the channel to keep it alive.
In order to keep your service host up, go with your #2 option (Subscribe to the faulted event on the service host). When faulted, you need to Abort the servicehost, new up a fresh instance, rewire the faulted event handler, and open the service host.
There's not much official documentation on this scenario, but here's an old post from an msdn blog describing what you're looking for.
http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx
As to the client, it also will need to recreate its channel to the server when said channel is faulted.

System.TimeoutException in WCF service C#

I have a problem with my WCF service. I'm getting thw following exception after the program runs three hours perfectly.
System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9843998. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout
I do not think that increasing the timeout would be a solution. I think the just would throw the exception a couple of minutes later. Maybe I have to change any settings on my listener server. Could it be that my machine close the port after a certain period of time?
I call my service like that:
IServices service = null;
service = ChannelFactory<IServices>.CreateChannel(
new BasicHttpBinding(),
new EndpointAddress(
port));
result = service.addAppointments(appList);
My listener:
ServiceHost host = new ServiceHost(service);
host.AddServiceEndpoint(typeof(
IServices),
new BasicHttpBinding(), port);
host.Open();
Thats all. No further settings were required up to now.
You can add through config the tracer for WCF. This will help you to find out where the problem is.
http://msdn.microsoft.com/en-us/library/ms733025.aspx
http://msdn.microsoft.com/en-us/library/ms732023.aspx

How to make/simulate persistent TCP connection?

It looks like WCF TCP connections are not persistent. First ping reply takes a while but subsequent processes take less time. After a while it takes long again -another re-connection?
SERVER> Started on net.tcp://0.0.0.0:999
CLIENT> Connection created to net.tcp://localhost:999 //Not a real connection, ready to connect
CLIENT> Ping reply in 1s163ms //First connection
CLIENT> Ping reply in 22ms //Already connected
CLIENT> Ping reply in 26ms
CLIENT> Ping reply in 24ms
CLIENT> Ping reply in 325ms //Re-connected
CLIENT> Ping reply in 19ms
CLIENT> Ping reply in 767ms //Re-connected
If it's true, what is the idle time value for a tcp connection before it will be disconnected? I need to keep the connection alive.
Update Modified code:
NetTcpBinding tcpBind = new NetTcpBinding();
tcpBind.ReliableSession.Enabled = true;
tcpBind.ReliableSession.Ordered = true;
tcpBind.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
ServiceHost svh = new ServiceHost(typeof(ServiceImplementation));
svh.AddServiceEndpoint(
typeof(WCFSimple.Contract.IService),
//new NetTcpBinding(),
tcpBind,
String.Format("net.tcp://{0}:{1}", ip, port));
svh.Open();
Now I got another error:
The action http://tempuri.org/IService/Pong is not supported by this endpoint. Only WS-ReliableMessaging February 2005 messages are processed by this endpoint.
Update I modified only server side and it caused the error. Then I modified client side's TCP as reliable messaging.
I don't think Ping is a good tool to test a TCP connection. Because Ping uses ICMP as its underlying protocol instead of TCP.
I suggest you create a WCF client, connect to the service and then check the TCP connection via some network sniffering tools or simply use netstat for quick check.
Normally, WCF connections are transient, though there is some connection pooling that goes on in the background.
Using net.tcp as the transport, persistent (long term) connections are possible. The code you've posted is one way to achieve that.
For more information, and some alternatives, check out What You Need To Know About One-Way Calls, Callbacks, And Events, an MSDN magazine article from October 2006.
Also of use are the IsInitiating and IsTerminating properties available on the OperationContract attribute.

Categories