Showing posts with label WCF. Show all posts
Showing posts with label WCF. Show all posts

Monday, April 7, 2014

WCF Discovery : Ad Hoc Discovery Client

WCF Discovery is a new feature which was shipped with WCF 4.0.WCF discovery is an implementation of the OASIS WS-Discovery specification.Think a scenario where  client application has the address of a specific service hard-coded into its configuration, then if that service moves, becomes temporarily unavailable, or is just too busy to handle requests, the client will not be able to communicate with it. WCF provides discovery and routing to address these issues. By implementing discovery client Application can locate the specific service address dynamically. As well as service can broadcasts its status to the all clients when service goes down or up.

There are two ways to implement WCF discovery.

  • Add Hoc Discovery
  • Manage Discovery

In this example I m going to explain Add Hoc Discovery client.In this client, service address not hard coded.Instead of that setting up the client endpoint address dynamically.

How this works ?

In Adhoc model clients send Probe message to the network .This message contains the information about the service which it wishes to connect. After service receives a Probe request, it can examine its contents, and if the probe matches the contract implemented by the service, it can respond to the client with a ProbeMatch message. TheProbeMatch message contains the service addressing information that the client needs to connect to the service.Client message uses the UDP protocol to send the probe message.

When implementing in order to  support above model service need to add specific endpoint call udpDiscoveryEndpoint and Service Discovery behavior to the service behaviors

what is udpDiscoveryEndpoint – This is a standard endpoint which used to implement the ad hoc mode of discovery.

<services>
<service name="Discovery.PTSService" behaviorConfiguration="discoveryBehaviour">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="httpBinding"
contract="Discovery.IPTSService" />
<!—new discovery endpoint-->
<endpoint kind="udpDiscoveryEndpoint"/>
</service>
</services>


What is Kind ?


udpDiscoveryEndpoint is standard endpoint .if we need to use standard endpoint we have to use kind instead of name. for more information http://msdn.microsoft.com/en-us/library/ee358762(v=vs.110).aspx


<serviceBehaviors>
<behavior name="discoveryBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />

<!-- service dicovery behaviors -->
<serviceDiscovery />
</behavior>
</serviceBehaviors>


Additionally we can set the scope for the service endpoint behaviors.which Adds the scope information for the endpoint that can be used in matching criteria for finding services.


Now our service is completed.(please make sure service is up and running)Now move the client implementation.


image


Client need to have reference to the System.ServiceModel.Discovery and your service.


image


static void Main(string[] args)
{
//initialize new discovery Client with UdpDiscoveryEndpoint
DiscoveryClient client = new DiscoveryClient(new UdpDiscoveryEndpoint());

// define the find criteria with serivce type
FindCriteria criteria = new FindCriteria(typeof(IPTSService));

// then clinet .Find
FindResponse services = client.Find(criteria);

client.Close();
}


Additionally FindCriteria can set the time out for service discovery. whether criteria can find service or not its return the output after the specified time.


criteria.Duration = TimeSpan.FromSeconds(50);


Lets run and see what happens.I have put watcher to the my services object..


image


Now you can see Find response contains all the required for the service invocation.

Thursday, April 3, 2014

The type 'System.ServiceModel.Routing.RoutingService', provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found

Recently I have created WCF router service and deployed to IIS. But once I run the my router service its gives me above error Sad smile.Normally this kind of errors happen when service couldn't find the service host reference. but in my router service its seems ok .

<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService" %>


Then I use full qualified name instead of the name as below.Bingo then its works Smile 


<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35"  %>

Wednesday, April 2, 2014

This message cannot support the operation because it has been copied

In order to implement few validations I have written separate method which expects message instance as parameter. In side that method I process the  input message . but once I try to run my service it throws above error and terminates the process Sad smile. after spending some time with the issue I could identify the issue.

according to the MSDN The body of a Message instance can only be consumed or written once. but I have tried several times to read message instance inside my validation logic.

from MSDN

“You can access the body of a Message only once, regardless of how it is accessed. A message object has a State property, which is initially set to Created. The three access methods described in the preceding list set the state to Written, Read, and Copied, respectively. Additionally, a Close method can set the state to Closed when the message body contents are no longer required. The message body can be accessed only in the Created state, and there is no way to go back to the Created state after the state has changed.”

There fore we need to use CreateMessageCopy method for reading the message.

   1: public bool Logic(Message message)
   2: {
   3:     MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
   4:  
   5:     var message1 = buffer.CreateMessage();
   7:  
   8:     buffer.Close();
   9:  
  10:     return true;
  11: }

Bingo its works Smile

Tuesday, April 1, 2014

WCF Asynchronous : Event Base pattern

When developing applications some time we have deal with the long running tasks.During the long running process its very import to to keep the UI responsive and feed updates to the user.When we comes to the service oriented architecture some times we have to deal with the long running services.Then UI does not hang while service works.To avoid such a behaviors we can use asynchronous pattern.

Basically WCF supports three type of Async patterns.

  • The event-based asynchronous pattern .
  • The IAsyncResult asynchronous pattern .
  • The task-based asynchronous pattern.

This simple example is related to the event based async pattern.

first we need to implement the service.

   1:  public class LongRunner : ILongRunner
   2:      {
   3:          public string InitiateLongRunner()
   4:          {
   5:              // for the sake of the simplicity im just delaying the method execution.
   6:              Thread.Sleep(TimeSpan.FromSeconds(5));
   7:              return "Long running process has completed";
   8:          }       
   9:      }



Service contract.


   1:   [ServiceContract]
   2:      public interface ILongRunner
   3:      {
   4:          [OperationContract]
   5:          string InitiateLongRunner(); 
   6:      }



Please make sure your service up and running.


In this method we don’t need to add any additional coding to service implementation in order to support the asynchronous behavior.


Client proxy creation.


Add service reference. 


image


Then go the advanced.


image


Then select “Generate asynchronous operation” radio button. (This will add async method to the service WSDL.)


Initiate the service call.


   1:  class Program
   2:      {
   3:          static void Main(string[] args)
   4:          {
   5:              using (MyClient.LongRunnerClient client = new MyClient.LongRunnerClient())
   6:              {
   7:                  // register the event. this event fires when the service operation has completed.
   8:                  client.InitiateLongRunnerCompleted += client_InitiateLongRunnerCompleted;
   9:   
  10:                  // call the long running operations
  11:                  client.InitiateLongRunnerAsync();
  12:                  Console.WriteLine("Long runner has started.");
  13:                  Console.WriteLine("Request is processing.");
  14:                  Console.Read();
  15:              }
  16:          }
  17:   
  18:          /// <summary>
  19:          /// Handles the service reply.
  20:          /// </summary>
  21:          /// <param name="sender"></param>
  22:          /// <param name="e"></param>
  23:          private static void client_InitiateLongRunnerCompleted(object sender, MyClient.InitiateLongRunnerCompletedEventArgs e)
  24:          {
  25:              Console.WriteLine(e.Result.ToString());
  26:          }
  27:      }



In Line 11 uses the async method than the original one . When we generate the WSDL including asynchronous methods, async method name came as original method name + “async”  word.


result can be taken from the async method handler event args.(e.Result).

Deploy WCF service without SVC file in IIS and WAS

Normally when we going to host WCF service in IIS or WAS need to have svc file. The Service.svc file is an XML-based file that must include an @ServiceHost directive. The directive identifies your
service, and it should include attributes that identify the service code language and the name
of the service.

But think a scenario where you have lots of services in a enterprise environment.Then you have to maintain lot of svc files.Its adds extra penalty to the developer as well as the deployment engineer.fortunately WCF 4.0  has shipped with new future called Configuration based activation which is capable for overcome this problem.

There are lo of WCF 4.0 features.Please refer MSDN . http://msdn.microsoft.com/en-us/library/dd456789(v=vs.100).aspx

When using CBA we don’t need to use and svc file instead of that Configuration-based activation takes the metadata that used to be placed in the .svc file and places it in the Web.config file.It use <serviceHostingEnvironment>/<serviceActivations> tags.

let see below example.we need to add below code to the web.config file.

CBAimage1

After deploy to the IIS(with out svc).

iis

finally

CBDemo

For additional information please refer : http://msdn.microsoft.com/en-us/library/ee358764(v=VS.110).aspx

Wednesday, July 10, 2013

load test application itself does not have an app.config file?

 

I am load testing a WCF project using VS2010 load testing manager , that uses an app.config file to load configuration properties. But the problem is load test application itself does not have an app.config file. there for what I have done is add the .config file to the ny load testing project and its works charmly Smile

Tuesday, July 2, 2013

Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].

 

Recently I have create WCF service and hosted in IIS 7.5 under was.

Then I investigate the reason and found the reason.In order to over come this issue we need to have both http,net.tcp protocols in hosted web application advanced settings under Behavior section.

image.

No connection could be made because the target machine actively refused it error in WAS hosted WCF service

 

Recently I have created wcf service which is on NetTCPBinding and hosted in WAS.But when I try to create proxy using WCFtestClient its always failed prompting this error. Sad smile

The reason for this is the host sent a reset signal, instead of an ack when the client tried to connect. It is therefore not a problem in the code. Either there is a firewall blocking the connection or the process that is hosting the service is not listening on that port.

  • There fore we need to marks service port  as allowed port in the server firewall by defining new rule.
  • Need to running NetTcpPort Sharing windows service and Net.Tcp  Distner adapter windows service.

image

After doing above two steps its works Smile Smile Smile

Friday, August 10, 2012

In C#, how to check if a TCP port is available?

When hosting wcf service which is use net tcp binding and without port sharing in a windows service , we should make sure the availability of our wcf port number. Other wise service doesn't start.

There fore as a best practice its is better to have code which will check the availability of the port when starting the service.This code should included to the service startup event. 

   1: protected override void OnStart(string[] args)
   2:        {
   3:            try
   4:            {
   5:                if (serviceHost != null)
   6:                {
   7:                    serviceHost.Close();
   8:                }
   9:  
  10:                PortChecker pc = new PortChecker();
  11:  
  12:                if (pc.IsPortAvailable())
  13:                {
  14:                    serviceHost = new ServiceHost(typeof(M3ISPlusService));
  15:                    serviceHost.Open();
  16:                }
  17:            }


ANd this is the port checker class



   1: public bool IsPortAvailable()
   2:         {
   3:             bool isAvailable = false;
   4:             TcpListener tcpListner = new TcpListener(GetServerIp(), GetPort());
   5:             Logger logger = Logger.GetLogger();
   6:  
   7:             try
   8:             {
   9:                 tcpListner.Start();
  10:                 isAvailable = true;
  11:             }
  12:             catch (Exception ex)
  13:             {
  14:                 logger.Log(ex.Message);
  15:             }
  16:  
  17:             finally
  18:             {
  19:                 try
  20:                 {
  21:                     tcpListner.Stop();
  22:                     tcpListner = null;
  23:                 }
  24:                 catch (Exception)
  25:                 {
  26:                     tcpListner = null;
  27:                 }
  28:             }
  29:  
  30:             return isAvailable;
  31:         }

To get port in code please refer my previous post :- Read End point address programmatically


Happy Coding :)

Friday, March 16, 2012

Method Overloading error in WCF

In normal behavior of  WCF if you try to implement method overloading in WCF service contract it will throw the an InvaildOperationException once you invoke the service.

[OperationContract]
[FaultContract(typeof (ServiceException))]
BasicDataDTO[] RetrieveGenericData(EBasicDataType genericType, string descriptionPart);

[OperationContract]
[FaultContract(typeof (ServiceException))]
BasicDataDTO[] RetrieveGenericData(string styleNo, int versionId, EBasicDataType genericType, string descriptionPart);
In generally above statement will throw the InvaildOperationException.To overcome this problem you have to put OperationContractAttribute with Name Property.
[OperationContract(Name = "GetGenericData")]
[FaultContract(typeof (ServiceException))]
BasicDataDTO[] RetrieveGenericData(EBasicDataType genericType, string descriptionPart);

[OperationContract(Name = "GetAllgenericData")]
[FaultContract(typeof (ServiceException))]
BasicDataDTO[] RetrieveGenericData(string styleNo, int versionId, EBasicDataType genericType, string descriptionPart);
In Object Oriented aspect above code is correct ,WCF always generate proxy using the WSDL.The problem is WSDL does not support the concepts like inheritance and overloading.