Thursday, April 19, 2012

WCF Discovery Underpinning

Incase you don't know what WCF Discovery is, please read this first

<endpoint kind="udpDiscoveryEndpoint" />

what is kind ?
A string that specifies the type of standard endpoint applied. The type must be registered in the <extensions> section or in machine.config.

Extensions?
<system.serviceModel>
    <extensions>    
        <behaviorExtensions>
            <add name="MyInspectorA" type="MyTypeA" />
            <add name="MyInspectorB" type="MyTypeB" />
        </behaviorExtensions>
    </extensions>
</system.serviceModel>


This extensible object pattern is used for extending the runtime behavior of the existing classes or to add custom state information.

[to be completed soon..]

Wednesday, April 18, 2012

WCF Call Back

Client subscribes to service and service calls clients back and that is what this is about.

1) A normal WCF contract for server(impementation) and client(for proxy)
[ServiceContract]
interface IMessage    
{
        [OperationContract]
        void AddMessage(string message);
 }
2) A special interface(not a contract) for server(proxy) and client(implementation)
 interface IMessageCallback    
{
        [OperationContract(IsOneWay = true)]
        void OnMessageAdded(string message, DateTime timestamp);
 }
3) Add subscribe mechanism to normal WCF contract (given in step 1)
   [ServiceContract(CallbackContract = typeof(IMessageCallback))]
    public interface IMessage {
        [OperationContract]
        void AddMessage(string message);

        [OperationContract]
        bool Subscribe();

        [OperationContract]
        bool Unsubscribe();
    }

4) Implentation of normal contract given in step 3
a) a list to store subscribers
private static readonly List<IMessageCallback> subscribers = new List<IMessageCallback>();
b) get subscriber(callback channel to client)
IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
c) add subscriber to list
subscribers.Add(callback);
complete code:

public bool Subscribe()
{
    try {
        IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
        if (!subscribers.Contains(callback))
            subscribers.Add(callback);
        return true;
    }
    catch {
        return false;
    }
}

public bool Unsubscribe()
{
    try {
        IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>();
        if (subscribers.Contains(callback))
            subscribers.Remove(callback);
        return true;
    }
    catch {
        return false;
    }
}
public void AddMessage(string message)
{
    subscribers.ForEach(delegate(IMessageCallback callback)
    {
        if (((ICommunicationObject)callback).State == CommunicationState.Opened)
        {
            callback.OnMessageAdded(message, DateTime.Now);        }
        else {
            subscribers.Remove(callback);
        }
    });
}
5) add a suitable binding in config
<endpoint address ="" binding="wsDualHttpBinding" contract="WCFCallbacks.IMessage">

6) Client implementation
a) implement call back contract(given in step 2)
b) dispose mechanism needed
c) a context is required
 [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class Sender : IMessageCallback, IDisposable
{
    private MessageClient messageClient; public void Go()
    {
        InstanceContext context = new InstanceContext(this);
        messageClient = new MessageClient(context, "WSDualHttpBinding_IMessage");

        for (int i = 0; i < 5; i++)
        {
            string message = string.Format("message #{0}", i);
            Console.WriteLine(">>> Sending "+message);
            messageClient.AddMessage(message);
        }

    }
public void OnMessageAdded(string message, DateTime timestamp)
    {
        Console.WriteLine("<<< Recieved {0} with a timestamp of {1}", message, timestamp);
    }

    public void Dispose()
    {
        messageClient.Unsubscribe();
        messageClient.Close();
    }
}

Courtesy

WCF Sessions vs ASP.Net Sessions

WCF sessions are different from ASP.Net sessions

  • 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 a few WCF 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(concurreny)
For simple and indepth overview on WCF Sessions check this blog

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--