Sunday, March 25, 2012

WCF Facts

  • A service behavior cannot be applied to a contract but a class
  • URI schemes
    • http://
    • https://
    • net.tcp://
    • net.pipe://
    • sb://
  •  
[to be continued]

Friday, March 16, 2012

How to block sites

It is very simple!

1)Find the 'hosts' file location in your PC. eg:Windows 7 = C:\Windows\System32\drivers\etc\

2) In 'Hosts' file properties uncheck the Read-only option

3)Open a notepad as administrator
4)In the notepad File->Open browse to  C:\Windows\System32\drivers\etc\ and open the 'hosts' file

5) If the site you want to block is www.bbc.com then add the following entries in the host file
0.0.0.0 bbc.com
0.0.0.0 www.bbc.com

6) Save hosts file

7)Close all exisitng browser windows and start a new one.Try accessing the blocked site!

---The End--- comment your thoughts please

Friday, March 9, 2012

WCF Durable Services quick and indepth overview

I love sessions in WCF . InstanceContextMode.PerSession so simple! But we know that session ends when the Server or the client restarts. That is when durable services makes an entry (from 3.5 onwards).

What is the deal? session ID is stored in disk/database?
Nope not just session id. But half marks for the answer because database/disk file is used.

Are you telling me that the whole server instance is serialised and placed in a data store?
Yes!!

Here is the explanation: After receiving a response from the service, the client will use the InstanceId(service instance guid) value on each subsequent operation invocation so that the client associates itself with the correct service instance.

So there needs to be some connectionstring info in config naturally:
<behaviors>
      <serviceBehaviors>
        <behavior>
          <persistenceProvider type=""
                               connectionStringName=""
                               persistenceOperationTimeout = "00:00:10"
                               lockTimeout="00:01:00"
                               serializeAsText="true"/>

eg: for type="System.ServiceModel.Persistence.SqlPersistenceProviderFactory, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

A couple of downloadable sql statements makes the database ready for Durable Services.
  • SqlPersistenceProviderSchema.sql
  • SqlPersistenceProviderLogic.sql
Let us talk about coding.
Now that serialisation is used the service class should have a [Serializable] attribute. Changes in service class are as follows(not interface/contract)

1) persistenceProvider behavior element(already discussed)
2) [Serializable] attribute
3) [DurableService] attribute: specifies that state information for your WCF service can be persisted to a persistence store, such as a database or file.
4) [DurableOperation] attribute: specifies that the state will be saved after the operation has completed.
  • [DurableOperation(CanCreateInstance = true)]  :Indicates whether a new service instance can be created.
  • [DurableOperation(CompletesInstance = true)]  :Indicates whether the service instance will be unloaded from memory and deleted from persistence once the operation has finished executing.
Few attributes and easy to learn!

CanCreateInstance property is a bit tricky so let us spend a few seconds on that.
  • CanCreateInstane=true can work only if it is an activation message(messages without an attached instance ID)
  • If this property has default value(false) then no 'new' instance will be created. But can persist to an existing service instance entry in the persistence store.
  • if your contract disallows sessions (System.ServiceModel.SessionMode.NotAllowed) , every DurableOperationAttribute attribute must have this property(CanCreateInstance) set to true.
  • If the contract allows sessions, then all operations with CanCreateInstance = true cannot be one way(IsOneWay=true).
Finally modify the endpoint configuration settings to reference a context binding, such as wsHttpContextBinding.
<endpoint address ="" binding="wsHttpContextBinding" contract="SimpleDurableService.IService1" />
This is necessary because a DurableOperationContext is used by the client to identify a specific service instance.
-------------[The End]------Comment your thoughts please

Thursday, March 8, 2012

WCF Binding Indepth

Let us start with a question: In fig 2, there are two protocols given in each channel stack. Which block in Fig 1 would you put/associate them?
Fig 1:End Points

Fig 2: WCF Runtime Architecture
 Yes, the answer is Binding. The binding controls what happens on the wire for an endpoint. It's essentially the recipe WCF follows to build a channel stack capable of transforming a stream of bytes (the message on the wire) to a WCF message.

[to be continue] --comment your thoughts please--

WCF Behaviour Indepth

A behavior is a special type of class that extends runtime behavior during the ServiceHost/ChannelFactory initialization process.

Eg: In wcf sessions there is an attribute called InstanceContextMode and this is a behaviour(applied to service).

Behaviour could also be applied to operations. Infact there are four types of behaviors: service, endpoint, contract, and operation as given in this table:


as we can see each type of behavior is also modeled by a different interface definition, but they all share the same set of methods

One thing to note is that IServiceBehavior doesn't have an ApplyClientBehavior method because service behaviors can't be applied to clients. Which also means other three behaviours can be applied to both clients and services.

As a WCF developer where all could you implement or deal with Behaviour?
1) Configuration
2) Code(C#)
3) Reflection/Powershell(not discussed here)

Configration:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="OurBehavior">
<serviceMetadata httpGetEnabled="True" />
</behavior>
code(C#)
ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
host.Description.Behaviours.Add(discoveryBehavior);

There is also a [CallbackBehavior]
Use the CallbackBehaviorAttribute attribute to configure or extend the execution behavior of a callback contract implementation in a client application(duplex). Eg:-

one use of Callbackbehaviour: if the client is a windows form and gets multiple call back calls and processing these call backs might block main UI thread. To prevent this you should do the following,
decorate the client call back with CallbackBehavior attrib. UseSynchronizationContext = false, Concurrenymode = concurrencymode.multiple and UseSynchronizationContext=false as given below.

[CallbackBehaviorAttribute(
  IncludeExceptionDetailInFaults= true,
  UseSynchronizationContext=false,
  ConcurrenyMode =ConcurrencyMode.Multiple
)]
public class Client : SampleDuplexHelloCallback

....
}

An alternative to this solution is to use the Background worker when making calls to the service. This will run outside the WinForms Synchronization context and allow incoming calls to run without blocking.
-End- please comment your thoughts

Wednesday, March 7, 2012

WCF Sessions in depth

How session works in WCF?
First of all it is different from ASP.Net.
  • ASP.NET sessions are always server-initiated.(WCF session is caller initated)
  • ASP.NET sessions are implicitly unordered(WCF session is processed in the order of reception)
  • ASP.NET sessions provide a general data storage mechanism across requests(not in WCF session except 'durable services')
In ASP.Net you can access session very easily

1) In config: <configuration>
  <sessionstate
      mode="inproc" />
1) and then in code : Session("Stocks") = "MSFT; VRSN; GE"

But in WCF, to manage sessions, we should learn about some concepts:
1) There is an attribute to enable session(SessionMode)
2) We should manage instancing ourselves (which is there for an entirely different purpose)
3) Instancing is related to binding, so we should learn about supporting bindings
4) We might even need to control the execution threads(concurrency)

Say a request comes for the first time in this URL http://someservice/function
then the follwing steps happen
1) an InstanceContext class is created
2) InstanceContext loads the appropriate class associated with the service(service instance)

Tip:The MaxConcurrentInstances(service behaviour) property specifies the maximum number of InstanceContext objects in the service.
When 50 calls come then all the existing InstanceContexts will be used and others will be created instantly
a) So 50 request = 50 InstanceContext + corresponding 50 service instance
      This is called PerCall
b) If for these 50 requests the service identifies the client and always serves it by a dedicated service object, then this type of service will be known as PerSession service as it recognizes the client and serves it by a single instance of service object.
 So 50 request = 1 InstanceContext + 1 service instance
          or
       50 request from one client + 25 request from another client = 2 instanceContext + 2 service instance.
c) if all the requests irrespective of client are served by a single instance of service objects, then the service will be known as Single service
  So 50 request from one client + 25 requests from another client = 1 InstanceContext + 1 service instance

It is worth noting there is an operationBehavior called ReleaseInstanceMode. We should not be bothered about it for now as by default instanceContextMode is taken in to consideration by WCF.
Tip 2: So based on the tip I had given earlier If InstanceContextMode is PerSession, the resulting value of MaxConcurrentInstances is the total number of sessions. And PerCall= number of concurrent calls. If a message arrives while the maximum number of InstanceContext objects already exist, the message is held until an InstanceContext object closes.

To configure sessions in WCF, one should know the following three elements:
1) InstanceContextMode
PerCall , PerSession and Single appears in WCF as service behaviour called InstanceContextMode

2) SessionMode
service contract has a session mode property with the following values
  • Allowed – Service can accept sessionful clients as well as sessionless.
  • Required – Service will entertain only those clients who have session, sessionless client cannot connect to service.
  • NotAllowed – Service can interact only with sessionless clients. Just opposite to Required.
3) Binding
Another thing to keep in mind is that all bindings do not support sessions. Only WS-*, NetTcpBinding and NetNamedPipeBinding have session support so selection of appropriate binding is necessary

Let me try to confuse you: if you want asp.net like sessions with cookies then use BasicHttpContextBinding

SessionID
Both client and server has sessionID. When session is enabled these sessionIDs are the same.
string sessionId = OperationContext.Current.SessionId; //server
string sessionId = proxy.InnerChannel.SessionId;///client
string sessionId2 = proxy2.InnerChannel.SessionId;///client (different session id for every proxy/client)

When it is percall there still exists session ID but with null value

you can test this yourself by letting a service method pass the session id and comparing it at client.

Let’s consolidate this. First a suitable binding should be there which makes the ground to support the session. Then SessionMode of service contract should be supportive so that service could allow session based requests and at last InstanceContextMode should be configured such that it responds in a session based manner

Another aspect worth noting is ConcurrenyMode property in ServiceBehavior. If the InstanceContextMode value is set to Single the result is that your service can only process one message at a time(we learned this) unless you also set the ConcurrencyMode value to Multiple(multi-threading). Concurrency is the term given to the control of the number of threads executing in an InstanceContext at the same time

So after learning everything about sessions wouldn't it be annoying to see some other attributes about session else where in WCF?
Yes! I am talking about the two other service behavior attributes

1) AutomaticSessionShutdown
Specifies whether to automatically close a session when a client closes an output session.
2) TransactionAutoCompleteOnSessionClose
Gets or sets a value that specifies whether pending transactions are completed when the current session closes without error.

Relationship with transactions
Only a service with a session can set TransactionAutoComplete to false.
And lastly don't forget to check out my blog on Durable Services to overcome the limitations of sessions in WCF.

Oops! we missed something.. WCF su rocks! It is Reliable Sessions, which supports reliable messaging.
Reliable messaging retries communication on failure and allows delivery assurance. Sessions maintain state for clients between calls. We can implement it like this:
<bindings>
    <wsHttpBinding>
        <binding name="Binding1">
            <reliableSession enabled="true" ordered="true" />
        </binding>
    </wsHttpBinding>
</bindings>

'ordered' is optional and is used to specify the order of arrival of messages(the way they are sent).
To make sure only clients that support reliable messaging access the service, do this:
[ServiceContract(SessionMode=SessionMode.Required)]

And lastly, there is something called ssl sessions which is different from wcf session. (you may also bing establishSecurityContext =false setting to learn more)

Exam Tip:
  • SessionMode is a service contract
  • InstanceContextMode,AutomaticSessionShutdown and TransactionAutoCompleteOnSessionClose are service behaviours (ConcurrenyMode as well)
  • reliableSession is a binding element
 ---The End-- comment your thoughts please

WCF Transactions in depth

Explaining the meaning of transaction and 'transaction isolation' is silly so I am skipping it. To be able to write transactional webservices is cool! How about writing services that can 'flow' transactions?

A flowed transaction is a situation in which a transaction id(say from database) is passed over the wire and used on the receiving side(WCF) to continue executing with in the same scope.


Let us learn about the attributes and properties that support transactions first and later see how they work together.
a. Operation(interface/service)
[OperationContract]
[TransactionFlow(TransactionFlowOption.Required)]
Other options are Allowed and Not Allowed.

b. Behavior (class/service level)
  • TransactionAutoCompleteOnSessionClose: Specifies whether pending transactions are completed when the current session closes.
  • TransactionIsolationLevel: Determines the isolation level of the transaction.
  • TransactionTimeout: Specifies the period in which a transaction has to complete.
      [ServiceBehavior(TransactionAutoCompleteOnSessionClose=true,
      TransactionIsolationLevel=IsolationLevel.ReadCommitted,
      TransactionTimeout="00:00:30")]
By default serializable transactions are created.

c. Operation (class/service level)
[OperationBehaviour(TransactionScopeRequired=true,TransactionAutoComplete=true)]
Defines transaction behaviour with in service.

Tip: A service instance is recycled by default based on the InstanceContextMode setting (eg:PerCall = recycle after every call). But if you want to use a fresh instance after the transaction is completed use
ReleaseInstanceMode eg:-
[OperationBehavior(
          ReleaseInstanceMode=ReleaseInstanceMode.AfterCall, TransactionAutoComplete=true
  )]
  public string  SampleMethod(string msg)
{
}
d.Client side Call
 using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew))
{

    try
   {

       //1st service


        ServiceReference1.Service1Client obj = new ServiceReference1.Service1Client();
        obj.UpdateData();

       //second service


        ServiceReference2.Service1Client obj1 = new ServiceReference2.Service1Client();
        obj1.UpdateData();
        ts.Complete();
    }
    catch (Exception ex)
   {
        ts.Dispose();
    }
}
The code can also be written like this:

TransactionOptions transactionOptions = new TransactionOptions ();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew,transactionOptions))
{

}

Transaction Batching
The relatively high cost of creating a transaction and committing it in every receive operation can be avoided with Transaction Batching service behavior.
<transactedBatching maxBatchSize="Integer" />


Exam Tip:
Service Behavior:
  • TransactionAutoCompleteOnSessionClose
  • TransactionIsolationLevel
  • TransactionTimeout
  • transactedBatching
Service Contract:

Operation Contract:
  • TransactionFlow
Operation Behaviour:
  • TransactionScopeRequired
  • TransactionAutoComplete
--The End--comment your thoughts please---

Tuesday, March 6, 2012

WCF Discovery In Depth

Service without discovery
Let us first look at a normal service call and then let us change it to make it 'discoverable'.
using (ServiceHost serviceHost = new ServiceHost(typeof(BlueCloudsService), baseAddress))
{
    // add endpoint of BlueClouds service
    serviceHost.AddServiceEndpoint(typeof(IBlueClouds), new WSHttpBinding(), string.Empty);

    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();
    // The service can now be accessed.
}

Discovery?
Discoverable = Clients can discover this service(BlueClouds). Again 'discover' seems to be a new term for web developers, so let us learn that quickly.
UDP is a multicast protocol with which you transmit once and is replicated by other networking components as needed and thus creates a broadcasting effect. So exploring/searching a service with UDP(or similar protocols) can be called discovery.
Making a service discoverable means helping it to be discovered using a protocol like UDP...simple! You can make it even simpler by having a centralised server(instead of UDP) called discovery proxy which clients and services could use. Latter is Managed and former is called Ad-hoc.

Teaser : Which all is correct?
             1) BlueClouds tell clients that it is discoverable.
             2) BlueClouds listen to calls from clients
             3) Clients ask(broadcast) if BlueClouds is present in the universe.
if  answer included 1 then will Blue clouds broadcast itself? what would it say: name/interface/url? should the service be online?
if answer includes 2, is it polling or event subscriber pattern?
if answer includes 3 then what question does it ask name/interface/url ? how did the client came to know about BlueClouds? should the service be online to be discovered?

To implement discovery two things are required.
#1 changes to make BlueClouds discoverable at server end
#2 changes at client's end to discover BlueClouds

#1 Steps to make BlueClouds discoverable at server end
1)  Add discovery behavior to the service
Add 'ServiceDiscoveryBehaviour' to Servicehost.behaviours.add()
2) Where should the service listen to? Or in otherwords add a endpoint.
Add 'UdpDiscoveryEndPoint' to serviceHost.AddServiceEndpoint()
using (ServiceHost serviceHost = new ServiceHost(typeof(BlueCloudsService), baseAddress))
{
    serviceHost.AddServiceEndpoint(typeof(IBlueClouds), new WSHttpBinding(), string.Empty);

    // ** DISCOVERY ** //
    // make the service discoverable by adding the discovery behavior
    ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
    serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());

   
    // ** DISCOVERY ** //
    // add the discovery endpoint that specifies where to publish the services
    serviceHost.Description.Endpoints.Add(new UdpDiscoveryEndpoint());
   
    // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();

    // The service can now be accessed.
    }

Teaser clue: WCF Discovery allows a client to search for a service based on different criteria including contract types, binding elements, namespace, scope, and keywords or version numbers. WCF Discovery enables runtime and design time discovery. To make a service discoverable offline(eg: WCF in IIS does not run always ) use a proxy service for discovery and let the client contact the service directly. Should we select #2 as answer? not yet.. ;-)

And if want to enable discovery for a specific endpoint and not whole service then EndpointDiscoveryBehavior can be used


#2 changes to make Clients discover BlueClouds
1) decide a criteria to find namespace, binding, elements, etc.
         FindCriteria(typeof(IBlueClouds))
2) instantiate DiscoveryClient class with an endpoint (eg: udp)
            new DiscoveryClient(new UdpDiscoveryEndpoint());
3) find using DiscoveryClient object

            discoveryClient.Find(new FindCriteria(typeof(ICalculator)));

        DiscoveryClient discoveryClient =
            new DiscoveryClient(new UdpDiscoveryEndpoint());

        Collection<EndpointDiscoveryMetadata> blueCloudServices =
            discoveryClient.Find(new FindCriteria(typeof(IBlueClouds)));

        discoveryClient.Close();

        if (blueCloudsServices.Count == 0)
        {
            Console.WriteLine("\nNo services are found.");
        }
        else
        {
            serviceAddress = blueCloudsServices[0].EndpointAddress;

        }

That was easy! those two classes made things easy for us: ServiceDiscoveryBehaviour and DiscoveryClient. Shouldn't we go deeper and find out what happens behind the screen? Just for fun!  we do that soon..

BlueClouds Annoucement
Here is another feature. This is optional.
BlueClouds can be configured to send out announcement messages.... "here i am.. this is me.. there's nowhere..".
Again we have 2 things to do
1) Change BlueClouds code
2) Change subscriber(client) code
Change BlueClouds code
The ServiceDiscoveryBehavior class has a property called AnnouncementEndpoints.
discoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint());
 the code looks like this:-
ServiceDiscoveryBehavior serviceDiscoveryBehavior = new ServiceDiscoveryBehavior();
serviceDiscoveryBehavior.AnnouncementEndpoints.Add(new UdpAnnouncementEndpoint());
serviceHost.Description.Behaviors.Add(serviceDiscoveryBehavior);


Change subscriber(client) code
The client needs to instantiate AnnouncementService class. And AnnouncementService has OnlineAnnouncementReceived and OfflineAnnouncementReceived events.

code:-
// Bring the subscriber online
serviceHost.Open();
// Create an AnnouncementService instance
AnnouncementService announcementService = new AnnouncementService();

// Subscribe the announcement events
announcementService.OnlineAnnouncementReceived += OnOnlineEvent;
announcementService.OfflineAnnouncementReceived += OnOfflineEvent;

// Create ServiceHost for the AnnouncementService
using (ServiceHost announcementServiceHost = new ServiceHost(announcementService))
{
    // Listen for the announcements sent over UDP multicast
    announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());
    announcementServiceHost.Open();
}


And when a message is recieved this is what happens
static void OnOnlineEvent(object sender, AnnouncementEventArgs e)
{
    Console.WriteLine("Received an online announcement from {0}",
e.EndpointDiscoveryMetadata.Address);
}


Through config: Service
<behaviors>
      <serviceBehaviors>
        <behavior name="helloWorldServiceBehavior">
          <serviceDiscovery>
            <announcementEndpoints>
              <endpoint kind="udpAnnouncementEndpoint"/>
            </announcementEndpoints>
          </serviceDiscovery>
        </behavior>
      </serviceBehaviors>
<system.serviceModel>
   <services>
      <service name="HelloWorldService" behaviorConfiguration="helloWorldServiceBehavior">
         <!-- Application Endpoint -->
         <endpoint address="endpoint0"
                   binding="basicHttpBinding"
                   contract="IHelloWorldService" />
         <!-- Discovery Endpoints -->
         <endpoint kind="udpDiscoveryEndpoint" />
        </service>
    </service>
<!-- Announcement Listener Configuration -->
   <service name="AnnouncementListener">
      <endpoint kind="udpAnnouncementEndpoint" />
   </service>
Client
<discoveryClient>
            <endpoint kind="discoveryEndpoint"
                      address="http://localhost:8000/ConfigTest/Discovery"
                      binding="customBinding"
                      bindingConfiguration="httpSoap12WSAddressing10"/>
            <findCriteria duration="00:00:10" maxResults="2">
              <types>
                <add name="IHelloWorldService"/>
              </types>
              <scopes>
                <add scope="http://www.microsoft.com/building42/floor1"/>
              </scopes>           
            </findCriteria>
          </discoveryClient>

--End--(behind the screen/underpinning blog is here.. )comment your thoughts please :)