Type serviceType = typeof(MyService);
host = new ServiceHost(serviceType);
ServiceEndpointCollection endpoints = host.Description.Endpoints;
foreach (ServiceEndpoint endpoint in endpoints)
{
if (endpoint.Name == "wsHttpEndPoint")
{
endpoint.Binding.CreateBindingElements().Find<HttpTransportBindingElement>().KeepAliveEnabled = false;
break;
}
}
The default behavior of WCF is to work with KeepAliveEnabled=true, so when WCF client proxy open connection and decide not to close it, the connection stay open because of the keep alive HTTP header (Connection=KeepAlive) that server forward to client.
if I want to change the default behavior and force the client proxy to be closed on each call, even if client did not call to proxy.close on its code. What do we have to do???
I thought that by changing the KeepAliveEnabled to false on the WCF service I can reach this goal. Unfortunately I was worng by changing this property to false nothing happned and the proxy still act the same.
Can someone explain what is this KeepAliveEnabled behavior means and how to use it? Is it works only on the WCF client side configuration?
Well probably the answer is yes. This property works only on the client side configuration and it also make sense.
If you still want to control the keep alive on the server side you can do it with this simple trick.
For this trick I use: WCF Message Inspector.
Now lets see some code example:
Step 1 create HeaderMessageInspector.cs
namespace CoregistrationPostingWindowsService
{
public class HeaderMessageInspector : IDispatchMessageInspector
{
#region IDispatchMessageInspector Members
public void BeforeSendReply(ref Message reply, object correlationState)
{
HttpResponseMessageProperty httpResponseProperty = new HttpResponseMessageProperty();
httpResponseProperty.Headers.Add(HttpRequestHeader.Connection, "close");
reply.Properties[HttpResponseMessageProperty.Name] = httpResponseProperty;
}
public object AfterReceiveRequest(ref Message request, IClientChannel channel,
InstanceContext instanceContext)
{
return null;
}
#endregion
}
}
Step 2 create HeaderEndpointBehavior.cs
namespace MyService
{
public class HeaderEndpointBehavior : IEndpointBehavior
{
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
throw new Exception("Behavior not supported on the consumer side!");
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
HeaderMessageInspector inspector = new HeaderMessageInspector();
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
}
public void Validate(ServiceEndpoint endpoint)
{
}
#endregion
}
}
Step 3 create HeaderBehaviorExtensionElement.cs
namespace MyService
{
public class HeaderBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(HeaderEndpointBehavior); }
}
protected override object CreateBehavior()
{
return new HeaderEndpointBehavior();
}
}
}
Step 4 Register the message inspector on our service
I will do it by code but you can do it also with configuration if you like.
Type serviceType = typeof(MyService);
host = new ServiceHost(serviceType);
ServiceEndpointCollection endpoints = host.Description.Endpoints;
foreach (ServiceEndpoint endpoint in endpoints)
{
if (endpoint.Name == "wsHttpEndPoint")
{
// Register the header endpoint with the message inspector.
endpoint.Behaviors.Add(new HeaderEndpointBehavior());
break;
}
}
host.Open();
After the message inspector registration we can now add to each Web Service call on the function:
public void BeforeSendReply(ref Message reply, object correlationState)
The custom HTTP header that will be send to client. We add the header Connection=close. This HTTP header mark to client to close connection immediately after the call, so even if the user forget to call to proxy.close() on its code the connection will be close automatically.
Well I really want to here your comments on this issue.
Bye Rotem.