Rashim's Blog

Archive for the ‘.NET’ Category


There is a special data type in .Net which is called string and it is a reference type, isn’t it? Of course it is but it also behaves much like a value type. That means it can directly accept values and does not require creating an instance. Have we ever thought for a single time how could we incorporate such a feature in our own class? Well, if we really need such type of feature we can easily implement it since operator overloading gives us the planetary for these purposes.

Operator overloading is a way to implement user-defined operator to be specified for operations where one or both of the operands are of a user-defined class or struct type. It also consents us to outline how the operators work with our class and struct. There are mainly three types of overload operators called unary, binary, and conversion. But not all operators of each type can be overloaded. According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to our C# class, which can accept any reasonably convertible data type without type casting. And such a kind of class can also be assigned to any convertible object or variable.  By using this operator we can design our class which can take a value as well. Let’s move to the code.

public class StringManipulationHelper
{
private string _value;
private static StringManipulationHelper _stringManipulationHelper;

public StringManipulationHelper()
{
_value = string.Empty;
}

public StringManipulationHelper(string submittedValue)
{
_value = submittedValue;
}

public static implicit operator StringManipulationHelper(string submittedValue)
{
_stringManipulationHelper = new StringManipulationHelper(submittedValue);
return _stringManipulationHelper;
}

public static implicit operator string(StringManipulationHelper objHelper)
{
return objHelper._value;
}
}

Now you can use in any way like this,

StringManipulationHelper helper = null;
or
StringManipulationHelper helper = "This is test";
or
var helper = new StringManipulationHelper();
or
var helper = new StringManipulationHelper("This is a Test");

Easy enough right? But it will help us a lot when we are in need such kinds of features.


As a series of article, this time, I am going to introduce you with Event-based asynchronous communication. I have used here same service operation of IAsyncResult asynchronous operation that I have mentioned earlier. Service implementation and hosting are also same with IAsyncResult asynchronous. So, in this case I will not go to explain service section again as well as will not go for in details all parts as i have discussed it clearly in other two posts. I would suggest you to have a look on the given links first.

To develop a client is just straight forward. Here I have shown you a console app as a client,

public class Program
 {
 static void Main(string[] args)
 {
 var proxy = new MessageServiceProxy("MessageServiceEndpoint");
 proxy.GetMessageCompleted += GetMessageCompleted;
 proxy.GetMessageAsync("HI");
 Console.WriteLine("waiting");
 Console.ReadLine();
 }
 static void GetMessageCompleted(object sender, GetMessageCompletedEventArgs e)
 {
 Console.WriteLine(e.Result.ToString(CultureInfo.InvariantCulture));
 }
 }

And its corresponding configuration has been given below,

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <system.serviceModel>
 <bindings />
 <client>
 <endpoint address="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/"
 binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService"
 name="MessageServiceEndpoint">
 <identity>
 <dns value="ServerCertificate" />
 </identity>
 </endpoint>
 </client>
 </system.serviceModel>
</configuration>

Now the important thing is how we develop our ServiceProxy which in our case is MessageServiceProxy .

public class MessageServiceProxy : ClientBase<IMessageService>, IMessageService
 {
 public event EventHandler<GetMessageCompletedEventArgs> GetMessageCompleted;
 private BeginOperationDelegate _onBeginGetMessage;

private EndOperationDelegate _onEndGetMessage;

private SendOrPostCallback _onGetMessageCompleted;

public MessageServiceProxy()
 {
 }

public MessageServiceProxy(string endpointConfigurationName) :
 base(endpointConfigurationName)
 {
 }

public IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object asyncState)
 {
 return Channel.BeginGetMessage(message, callback, asyncState);
 }

public string EndGetMessage(IAsyncResult result)
 {
 return Channel.EndGetMessage(result);
 }

private IAsyncResult OnBeginGetMessage(object[] inValues, AsyncCallback callback, object asyncState)
 {
 var message = ((string)(inValues[0]));
 return BeginGetMessage(message, callback, asyncState);
 }

private object[] OnEndGetMessage(IAsyncResult result)
 {
 string retVal = Channel.EndGetMessage(result);
 return new object[] {
 retVal};
 }

private void OnGetMessageCompleted(object state)
 {
 if ((GetMessageCompleted != null))
 {
 var e = ((InvokeAsyncCompletedEventArgs)(state));
 GetMessageCompleted(this, new GetMessageCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState));
 }
 }

public void GetMessageAsync(string message)
 {
 GetMessageAsync(message, null);
 }

private void GetMessageAsync(string message, object userState)
 {
 if ((_onBeginGetMessage == null))
 {
 _onBeginGetMessage = OnBeginGetMessage;
 }
 if ((_onEndGetMessage == null))
 {
 _onEndGetMessage = OnEndGetMessage;
 }
 if ((_onGetMessageCompleted == null))
 {
 _onGetMessageCompleted = OnGetMessageCompleted;
 }
 InvokeAsync(_onBeginGetMessage, new object[] {
 message}, _onEndGetMessage, _onGetMessageCompleted, userState);
 }
 }

Here I have used three delegates namely onBeginGetMessage, onEndGetMessage and onGetMessageCompleted and these three delegates will register when we first call GetMessageAsync() method. onGetMessageCompleted  is a SendOrPostCallback which represents a callback method that we want to execute when a message is to be dispatched to a synchronization context.

Finally the GetMessageCompletedEventArgs,

public class GetMessageCompletedEventArgs : AsyncCompletedEventArgs
 {
 private readonly object[] _results;

public GetMessageCompletedEventArgs(object[] results, Exception exception, bool cancelled, object userState) :
 base(exception, cancelled, userState)
 {
 _results = results;
 }

public string Result
 {
 get
 {
 RaiseExceptionIfNecessary();
 return ((string)(_results[0]));
 }
 }
 }

Download Source code


We are very well-versed that WCF service operations can be implemented asynchronously or synchronously .And the clients can call service operations synchronously or asynchronously since asynchronous service operations can be calling synchronously and vice versa. There are three ways to implement asynchronous operations

As a series of sequence, in this post, I am going to use IAsyncResult asynchronous operation but we should keep in mind that this pattern is no longer recommended for further development. If we know these three mechanisms of asynchronous operation it would be easier for us to architect our large distributed system based on asynchronous service. Before going to our implementation I would recommend you to have a look on APM Model first. I would like to Organize todays article in three steps; Service Implementation, Service Hosting and Client

Service Implementation

In IAsyncResult asynchronous system asynchronous operations require Begin and End methods.


[ServiceContract]
 public interface IMessageService
 {
 [OperationContract(AsyncPattern = true)]
 IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object state);

string EndGetMessage(IAsyncResult asyncResult);
 }

In the service contract, I declare an asynchronous method pair according to the APM. The BeginGetMessage method takes a parameter, a callback object, and a state object, and returns an IAsyncResult while EndGetMessage method takes an IAsyncResult and returns the value. Since the service operation returns IAsyncResult we have to implement it first. And the implementation has been given below,


public class AsyncResult : IAsyncResult,IDisposable
 {
 private AsyncCallback _callback;
 private object _state;
 private ManualResetEvent _manualResetEvent;

public AsyncResult(AsyncCallback callback, object state)
 {
 _callback = callback;
 _state = state;
 _manualResetEvent = new ManualResetEvent(false);
 }

public bool IsCompleted
 {
 get { return _manualResetEvent.WaitOne(0, false); }
 }

public WaitHandle AsyncWaitHandle
 {
 get { return _manualResetEvent; }
 }

public object AsyncState
 {
 get { return _state; }
 }
 public ManualResetEvent AsyncWait
 {
 get { return _manualResetEvent; }

 }
 public bool CompletedSynchronously
 {
 get { return false; }
 }

public void Completed()
 {
 _manualResetEvent.Set();
 if (_callback != null)
 _callback(this);
 }

 public void Dispose()
 {
 _manualResetEvent.Close();
 _manualResetEvent = null;
 _state = null;
 _callback = null;
 }
 }

AsyncResult implements IAsyncResult that has some properties like AsyncCallback, state object and a ManualResetEvent, which handle waiting for asynchronous operation. IsCompleted is used to specify that the operation is completed asynchronously. In the Complete() method ManualResetEvent has been set, which means that the event is signaled now and any other awaiting thread can follow.

Now for our MessageServiceOperation I create MessageAsyncResult which just inherit from AsyncResult to add a Message property.


public class MessageAsyncResult : AsyncResult
 {
 public string Message { get; private set; }
 public MessageAsyncResult(string message, AsyncCallback callback, object state)
 : base(callback, state)
 {
 Message = message;
 }
 }

Now implementing the service operations.


public class MessageService : IMessageService
 {
 public IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object state)
 {
 var replyMessage = string.Format("{0}{1}","Server says :",message);
 var messageAsyncResult = new MessageAsyncResult(replyMessage, callback, state);
 ThreadPool.QueueUserWorkItem(CompleteProcess, messageAsyncResult);

return messageAsyncResult;
 }

private void CompleteProcess(object state)
 {
 var messageAsyncResult = state as MessageAsyncResult;
 messageAsyncResult.Completed();
 }

public string EndGetMessage(IAsyncResult asyncResult)
 {
 var messageAsyncResult = asyncResult as MessageAsyncResult;
 messageAsyncResult.AsyncWait.WaitOne();
 return messageAsyncResult.Message;
 }
 }

In the BeginGetMessage () method I create an instance of MessageAsyncResult by passing appropriate parameters to it then call ThreadPool.QueueUserWorkItem() method to add a method to waiting queue for execution. The method CompleteProcess() will run whenever a thread becomes available and it finally call the Completed() method to release the thread and allow the other operations to execute. In the EndGetMessage () method, I call the WaitOne() method of its ManualResetEvent to wait until the current execution ends then return the Result property.

Service Hosting

This is also very simple. Here I have used a console app which will be used as a server,


class Program
 {
 static void Main(string[] args)
 {
 var svcHost = new ServiceHost(typeof(MessageService));
 Console.WriteLine("Available Endpoints :\n");
 svcHost.Description.Endpoints.ToList().ForEach(endpoints => Console.WriteLine(endpoints.Address.ToString()));
 svcHost.Open();
 Console.ReadLine();
 }
 }

And the configuration for that,


<configuration>
 <system.serviceModel>
 <behaviors>
 <serviceBehaviors>
 <behavior name="">
 <serviceMetadata httpGetEnabled="true" />
 <serviceDebug includeExceptionDetailInFaults="false" />
 </behavior>
 </serviceBehaviors>
 </behaviors>
 <services>
 <service name="Rashim.Rnd.WCF.Asynchronous.Services.MessageService">
 <endpoint address="" binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService">
 <identity>
 <dns value="localhost" />
 </identity>
 </endpoint>
 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
 <host>
 <baseAddresses>
 <add baseAddress="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/" />
 </baseAddresses>
 </host>
 </service>
 </services>
 </system.serviceModel>
</configuration>

Client

Now how client could consume this service.? Here I have given a simple console app to consume this service,


public class Program
 {
 static void Main(string[] args)
 {
 var channelFactory = new ChannelFactory<IMessageService>("MessageServiceEndpoint");
 var proxy = channelFactory.CreateChannel();
 var message = Console.ReadLine();
 while (message.Equals("exit",StringComparison.CurrentCultureIgnoreCase)==false)
 {
 proxy.BeginGetMessage(message, ClientCallBack, proxy);
 message = Console.ReadLine();
 }
 }

private static void ClientCallBack(IAsyncResult ar)
 {
 var res = ar.AsyncState as IMessageService;
 if (res != null)
 {
 var message = res.EndGetMessage(ar);
 Console.WriteLine(message);
 }
 }
 }

And the configuration file for this is,


<configuration>
 <system.serviceModel>
 <bindings />
 <client>
 <endpoint address="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/"
 binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService"
 name="MessageServiceEndpoint">
 <identity>
 <dns value="ServerCertificate" />
 </identity>
 </endpoint>
 </client>
 </system.serviceModel>
</configuration>

That’s it. Download Source code.


WebSocket, like as TCP, is a bi-directional, full-duplex communication channel over a single TCP connection but it shortens abundant complications close to bi-directional communication as well as connection management which we typically comprehend while using TCP. WebSocket channels start as normal HTTP channels which then upgraded to WebSocket channels by using handshaking, allowing cooperative TCP communication between client and server.

WCF hosts provision for WebSockets over the standard HTTP ports 80 and 443. The standard HTTP port allows WebSockets to communicate across the web through mediators. WCF introduces two standard bindings to support communication over a WebSocket transport.

  • NetHttpBinding
  • NetHttpsBinding

These bindings are designed for consuming WebSocket services and will perceive whether they are used with a request-reply contract or duplex contract and change their behavior according to it. They will use HTTP/HTTPS for request-reply contracts and WebSockets for duplex contracts. We can override this behavior by using WebSocketTransportUsage setting

  • Always – Enforce to use WebSockets.
  • Never – Stops to use WebSockets.
  • WhenDuplex – This is the default value.

Let’s move into the code to see how we could implement WCF service and clients that will communicate over WebSockets.

Define callback Contract

    public interface INotificationServiceCallback
    {
        [OperationContract(IsOneWay = true)]
        void OnNotificationSend(Notification notification);
    }

Clients will implement this contract through which the service can send messages back to the clients. To have a better understanding how duplex channel works I would recommend you to have a look on this link.

Define the service contract

    [ServiceContract(CallbackContract = typeof(INotificationServiceCallback))]
    public interface INotificationService
    {
        [OperationContract]
        void SendNotification(Notification notification);

        [OperationContract]
        void SubscribeForNotification(List<NotificationType> notificationTypes);

        [OperationContract]
        void UnsubscribeForNotification(List<NotificationType> notificationTypes);
    }

Here INotificationServiceCallback has been specified as the callback contract.

Implement the service contract

    public class NotificationServiceService : INotificationService
    {
        private INotificationServiceCallback Subscriber
        {
            get { return OperationContext.Current.GetCallbackChannel<INotificationServiceCallback>();  }
        }

        public void SendNotification(Notification notification)
        {
            NotificationManager.Instance.SendNotification(notification, Subscriber);
        }

        public void SubscribeForNotification(List<NotificationType> notificationTypes)
        {
            NotificationManager.Instance.AddSubscriber(Subscriber, notificationTypes);
        }

        public void UnsubscribeForNotification(List<NotificationType> notificationTypes)
        {
            NotificationManager.Instance.RemoveSubscriber(Subscriber, notificationTypes);
        }
    }

In the implementation, we retain the callback channel using the OperationContext which has been passed to the NotificationManager and finally NotificationManager does the rest of the Jobs.

Implement Notification Manager

    public class NotificationManager
    {
        private volatile static NotificationManager _notificationManager = null;
        private static readonly object SyncLock = new object();
        private NotificationManager()
        {
            Subscribers = new Dictionary<INotificationServiceCallback, List<NotificationType>>();
            Notifications = new List<Notification>();
        }

        public Dictionary<INotificationServiceCallback, List<NotificationType>> Subscribers { get; private set; }
        public List<Notification> Notifications { get; private set; }
        public static NotificationManager Instance
        {
            get
            {
                lock (SyncLock)
                {
                    if (_notificationManager == null)
                    {
                        lock (SyncLock)
                        {
                            _notificationManager = new NotificationManager();
                        }
                    }
                }
                return _notificationManager;
            }
        }

        public void AddSubscriber(INotificationServiceCallback subscriber, List<NotificationType> notificationType)
        {
            if (!Subscribers.ContainsKey(subscriber))
                Subscribers.Add(subscriber, notificationType);
            else
            {
                var newNotificationType = notificationType.Where(n => Subscribers[subscriber].Any(n1 => n1 != n));
                Subscribers[subscriber].AddRange(newNotificationType);
            }
        }

        public void RemoveSubscriber(INotificationServiceCallback subscriber, List<NotificationType> notificationTypes)
        {
            if (Subscribers.ContainsKey(subscriber))
            {
                notificationTypes.ForEach(notificationType => Subscribers[subscriber].Remove(notificationType));

                if (Subscribers[subscriber].Count < 1)
                    Subscribers.Remove(subscriber);
            }
        }

        public void AddNotification(Notification notification)
        {
            if (!Notifications.Contains(notification))
                Notifications.Add(notification);
        }

        public void RemoveNotification(Notification notification)
        {
            if (Notifications.Contains(notification))
                Notifications.Remove(notification);

        }

        public void SendNotification(Notification notification, INotificationServiceCallback sender)
        {
            foreach (var existingSubscriber in Subscribers)
            {
                if (existingSubscriber.Value.Any(n => n == notification.NotificationType) && existingSubscriber.Key != sender)
                {
                    if (((ICommunicationObject)existingSubscriber.Key).State == CommunicationState.Opened)
                    {
                        existingSubscriber.Key.OnNotificationSend(notification);
                    }
                }
            }
        }
    }

As we see, NotificationManager maintains a dictionary to hold the client list whose have been subscribed for getting the notifications for different notification types. If any client broadcast messages with Notification types, the subscribers who only subscribe to get the notification for these notification types will get these messages. The code is itself self-explanatory. If you go through on the code portion you will easily have an idea about that.

Service configuration

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
     <compilation debug="true" targetFramework="4.5" />
     <httpRuntime targetFramework="4.5" />
  </system.web>
   <system.serviceModel>
        <protocolMapping>
          <add scheme="http" binding="netHttpBinding" />
        </protocolMapping>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    <system.webServer>
        <directoryBrowse enabled="true" />
    </system.webServer>
</configuration>

NetHttpBinding has been used for the default endpoints. If you want to acquaint a bit more about the configuration updates, I would suggest having a look on that.

Okay Service Portion has been done. Now, lets move to client portions,

Implement callback contract and Define Client

    class Program : INotificationServiceCallback
    {
        private NotificationServiceClient _notificationServiceClient;
        private InstanceContext _instanceContext;
        private readonly List<NotificationType> _notificationTypes = Enum.GetValues(typeof(NotificationType)).Cast<NotificationType>().ToList();

        public NotificationServiceClient NotificationServiceClient
        {
            get
            {
                return _notificationServiceClient ??
                       (_notificationServiceClient = new NotificationServiceClient(CallbackInstance,
                                                                                   "netHttpBinding_INotificationService"));
            }
        }

        public InstanceContext CallbackInstance
        {
            get { return _instanceContext ?? (_instanceContext = new InstanceContext(this)); }
        }

        static void Main(string[] args)
        {
            var objProgram = new Program();
            Console.WriteLine("Write exit to shut down....\n");
            Console.WriteLine("Wait...Subscribing for notifications\n");
            objProgram.SubscribeForNotification();
            Console.WriteLine("Subscription done...Now you can send notifacation\n");
            var readMsg = Console.ReadLine();

            while (readMsg.ToString(CultureInfo.InvariantCulture).ToLower().Equals("exit") == false)
            {
                objProgram.SendNotification(readMsg);
                Console.WriteLine("Notification has been send......\n");
                readMsg = Console.ReadLine();
            }
            objProgram.UnsubscribeForNotification();
        }

        public void OnNotificationSend(Notification notification)
        {
            Console.WriteLine(string.Format("New Notification Received\n\nMessage :{0}\nTime :{1}\n\n", notification.NotificationMsg, notification.PostingTime));
        }

        private void SubscribeForNotification()
        {
            NotificationServiceClient.SubscribeForNotification(_notificationTypes);
        }

        private void UnsubscribeForNotification()
        {
            NotificationServiceClient.UnsubscribeForNotification(_notificationTypes);
        }

        private void SendNotification(string msg)
        {
            NotificationServiceClient.SendNotification(new Notification()
            {
                NotificationMsg = msg,
                PostingTime = DateTime.Now
            });
        }
    }

The client application has a property of InstanceContext and NotificationServiceClient, also it specifies the implementation of the INotificationServiceCallback interface. When a client subscribes for the notifications to the service, the service will send the notifications to the client using the callback contract specified.

Implement NotificationServiceClient

    public class NotificationServiceClient : DuplexClientBase<INotificationService>, INotificationService
    {
        public NotificationServiceClient(InstanceContext callbackInstance) :
            base(callbackInstance)
        {
        }

        public NotificationServiceClient(InstanceContext callbackInstance, string endpointConfigurationName) :
            base(callbackInstance, endpointConfigurationName)
        {
        }

        public void SendNotification(Notification notification)
        {
            Channel.SendNotification(notification);
        }

        public void SubscribeForNotification(List<NotificationType> notificationTypes)
        {
            Channel.SubscribeForNotification(notificationTypes);
        }

        public void UnsubscribeForNotification(List<NotificationType> notificationTypes)
        {
            Channel.UnsubscribeForNotification(notificationTypes);
        }
    }

Client Configuration

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netHttpBinding>
        <binding name="NetHttpBinding_INotificationService">
          <webSocketSettings transportUsage="Always" />
        </binding>
      </netHttpBinding>
    </bindings>
    <client>
      <endpoint address="ws://localhost/websocket/NotificationService.svc"
          binding="netHttpBinding"
          contract="Rashim.RND.WCF.WebSockect.Interfaces.INotificationService"
             bindingConfiguration="NetHttpBinding_INotificationService"
          name="netHttpBinding_INotificationService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

This is as usual and not any special, what you need to do in the client configuration is to specify the client side endpoint using the NetHttpBinding.

Finally DataContracts

    [DataContract]
    public class Notification
    {
        [DataMember]
        public string NotificationMsg { get; set; }
        [DataMember]
        public DateTime PostingTime { get; set; }
        [DataMember]
        public NotificationType NotificationType { get; set; }
    }
    [DataContract]
    public enum NotificationType
    {
        [EnumMember]
        General,
        [EnumMember]
        Greetings
    }

Using Source code

You need to host the Rashim.RND.WCF.WebSockect.Services in IIS8 and then put the appropriate endpoint address to the client configuration file. After completing the Service hosting, you need to run the two instances of Rashim.RND.WCF.WebSockect.Clients then you can send message from instance to another one just like the given figure below.

WebSocketDemo
 References: 

Download SourceCode.

 

Though Performance blocking and Sluggishness are the tailbacks for any application, we can easily overcome these bottlenecks by using asynchronous programming. But old-style practice for asynchronous programming is not way easy enough to write, debug and maintain. So what is the contemporary approach??

Well, In my view, this is Task based asynchronous programming, which is updated in .Net 4.5 through the use of keywords await and async. But what do async and await do? async and await are the way of controlling continuation. When a method uses the async keyword, it means it is an asynchronous method, which might have an await keyword inside, and if it has an await keyword, async will activate it. So, simply async activates the await, from which point, the asynchronous has been started. There is a nice explanation that has been given here.

In WCF we can also consider an asynchronous operation while the service operation creates a delaying call. There are three ways to implement asynchronous operations

In this post I am going to use task-based asynchronous operation since this is the most contemporary strategy.

Okay. Let’s move to the code,

A very simple Service contract such as,

 [ServiceContract]
 public interface IMessage
 {
     [OperationContract]
     Task<string> GetMessages(string msg);
 }

With this simple contract, the implementation is just straight forward,

 public class MessageService : IMessage
 {
    async Task<string> IMessage.GetMessages(string msg)
    {
       var task = Task.Factory.StartNew(() =>
                                      {
                                          Thread.Sleep(10000);
                                          return "Return from Server : " + msg;
                                      });
      return await task.ConfigureAwait(false);
    }
 }

Here, the method is marked with the async keyword, which means it might use await keyword inside. It also means that the method will be able to suspend and then resume asynchronously at await points. Moreover, it points the compiler to boost the outcome of the method or any exceptions that may happen into the return type.

Service hosting,

 class Program
 {
     static void Main(string[] args)
     {
        var svcHost = new ServiceHost(typeof (MessageService));
        Console.WriteLine("Available Endpoints :\n");
        svcHost.Description.Endpoints.ToList().ForEach(endpoints=> Console.WriteLine(endpoints.Address.ToString()));
        svcHost.Open();
        Console.ReadLine();
     }
 }

Finally Service Configuration,

<?xml version="1.0"?>
 <configuration>
     <system.serviceModel>
       <services>
          <service name="Rashim.RND.WCF.Asynchronous.ServiceImplementation.MessageService">
             <host>
                 <baseAddresses>
                     <add baseAddress="net.Tcp://localhost:8732/"/>
                     <add baseAddress="http://localhost:8889/"/>
                 </baseAddresses>
             </host>
             <endpoint address="Tcp" binding="netTcpBinding" contract="Rashim.RND.WCF.Asynchronous.Services.IMessage"/>
             <endpoint address="Http" binding="basicHttpBinding" contract="Rashim.RND.WCF.Asynchronous.Services.IMessage">
                 <identity>
                      <dns value="localhost"/>
                 </identity>
             </endpoint>
             <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
       </services>
       <behaviors>
          <serviceBehaviors>
             <behavior>
                 <serviceMetadata/>
             </behavior>
          </serviceBehaviors>
       </behaviors>
     </system.serviceModel>
     <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup>
</configuration>

After Configuring the service,we need to configure the client app to consume the service.

A simple Console Application(Client),

class Program
 {
    static void Main(string[] args)
    {
       GetResult();
       Console.ReadLine();
    }

    private async static void GetResult()
    {
       var client = new Proxy("BasicHttpBinding_IMessage");
       var task = Task.Factory.StartNew(() => client.GetMessages("Hello"));
       var str = await task;
       str.ContinueWith(e =>
       {
          if (e.IsCompleted)
           {
              Console.WriteLine(str.Result);
           }
       });
      Console.WriteLine("Waiting for the result");
    }
 }

Client Configuration,

<?xml version="1.0"?>
 <configuration>
   <system.serviceModel>
     <bindings>
       <basicHttpBinding>
         <binding name="BasicHttpBinding_IMessage" />
       </basicHttpBinding>
     </bindings>
     <client>
       <endpoint address="http://localhost:8889/Http" binding="basicHttpBinding"
          bindingConfiguration="BasicHttpBinding_IMessage" contract="Rashim.RND.WCF.Asynchronous.Services.IMessage"
           name="BasicHttpBinding_IMessage" />
     </client>
   </system.serviceModel>
 </configuration>

Finally,proxy class is given below through which the client will consume the services.

public class Proxy : ClientBase<IMessage>, IMessage
 {
    public Proxy()
    {
    }
    public Proxy(string endpointConfigurationName) :
    base(endpointConfigurationName)
    {
    }
    public Task<string> GetMessages(string msg)
    {
      return Channel.GetMessages(msg);
    }
 }

That’s it. Very easy stuff though. You can download the source code from here.


In WCF, a service can call back to its clients. That is to say that, at the time of call back, the service behaves as a client as well as the client becomes the service, and the client must assist hosting the call back object. To support call back, the underlying transport of the binding must support bidirectional. So, for the nature of connectionless, we cannot use all bindings for the call back operation. For instance, BasicHttpBinding or WsHttpBinding does not support callback while WsDualHttpBinding supports it, because this binding establishes two HTTP channel to do that; one for client to service another for service to client. Also, NetTcpBinding and NetNamedPipeBinding supports callback since their underlying transport is bidirectional.

Callback service can be supported by using CallbackContract property in the ServiceContract attribute. Only one callback contract is allowed for a service contract. After defining a callback contract, we require to set up the client for up keeping the callback and also to offer the callback endpoint to the service for each and every call.

In the example given below, the callback contract defines the operations to which the service can call on the client endpoint

public interface INotificationServiceCallBack
{
    [OperationContract(IsOneWay = true)]
    void OnNotificationSend(string message);
}

The implementation of this Service Contract,

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class NotificationServiceCallBack : INotificationServiceCallBack
{
    public void OnNotificationSend(string message)
    {
        Console.WriteLine(message);
        Console.ReadLine();
    }
}

Here CallbackBehavior refers how the callback of this operation will act which is similar to ServiceBehavior.

And the service contract has been defined like the way given below,

[ServiceContract(CallbackContract = typeof(INotificationServiceCallBack))]
public interface INotificationServices
{
    [OperationContract]
    void SendNotification(string message);
}

To make a way around for the service to call, clients must expose an endpoint to the service. This has been done by the following way,

public class Program
{
    public static INotificationServices Proxy
    {
        get
        {
            var ctx = new InstanceContext(new NotificationServiceCallBack());
            return new DuplexChannelFactory<INotificationServices>(ctx, "WSDualHttpBinding_INotificationServices").CreateChannel();
        }
    }
    static void Main(string[] args)
    {
        Proxy.SendNotification("Are u ready?");
        Console.ReadLine();
    }
}

Here InstanceContext is the execution scope of inner most service instance. It provides a constructor that takes the service instance to the host.

And now service implementation,

public class NotificationService : INotificationServices
{
    public INotificationServiceCallBack Proxy
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel<INotificationServiceCallBack>();
        }
    }
    public void SendNotification(string message)
    {
        Console.WriteLine("\nClient says :" + message);
        Proxy.OnNotificationSend("Yes");
    }
}

In the above example, we see that the service has the proxy of INotificationServiceCallBack and call its operation which the clients will handle.

That’s it. Now the total code portion that i have used here has been given,

Services and Implementations,

public interface INotificationServiceCallBack
{
    [OperationContract(IsOneWay = true)]
    void OnNotificationSend(string message);
}

 

[ServiceContract(CallbackContract = typeof(INotificationServiceCallBack))]
public interface INotificationServices
{
    [OperationContract]
    void SendNotification(string message);
}
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class NotificationServiceCallBack : INotificationServiceCallBack
{
    public void OnNotificationSend(string message)
    {
        Console.WriteLine(message);
        Console.ReadLine();
    }
}
public class NotificationService : INotificationServices
{
    public INotificationServiceCallBack Proxy
    {
        get
        {
            return OperationContext.Current.GetCallbackChannel<INotificationServiceCallBack>();
        }
    }

    public void SendNotification(string message)
    {
        Console.WriteLine("\nClient says :" + message);
        Proxy.OnNotificationSend("Yes");
    }
}

Server and its configuration,

class Program
{
    static void Main(string[] args)
    {
        var svcHost = new ServiceHost(typeof(NotificationService));
        svcHost.Open();
        Console.WriteLine("Available Endpoints :\n");
        svcHost.Description.Endpoints.ToList().ForEach(endpoint => Console.WriteLine(endpoint.Address.ToString()));
        Console.ReadLine();
        svcHost.Close();
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="Rashim.RND.WCF.CallBack.Services.NotificationService">
        <host>
          <baseAddresses>
            <add baseAddress = "net.Tcp://localhost:8732/"/>
            <add baseAddress="http://localhost:8888"/>
          </baseAddresses>
        </host>
        <endpoint address="CallbackService" binding="netTcpBinding" contract="Rashim.RND.WCF.CallBack.Interfaces.INotificationServices"/>
        <endpoint address="CallbackService" binding="wsDualHttpBinding" contract="Rashim.RND.WCF.CallBack.Interfaces.INotificationServices"/>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
        <endpoint address="http://localhost:8888/mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Client and its Configuration,

public class Program
{
    public static INotificationServices Proxy
    {
        get
        {
            var ctx = new InstanceContext(new NotificationServiceCallBack());
            return new DuplexChannelFactory<INotificationServices>(ctx, "WSDualHttpBinding_INotificationServices").CreateChannel();
        }
    }
    static void Main(string[] args)
    {
        Proxy.SendNotification("Are u ready?");
        Console.ReadLine();
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:8888/CallbackService" binding="wsDualHttpBinding" contract="Rashim.RND.WCF.CallBack.Interfaces.INotificationServices" name="WSDualHttpBinding_INotificationServices">
      </endpoint>
      <endpoint address="net.tcp://localhost:8732/CallbackService" binding="netTcpBinding"
 contract="Rashim.RND.WCF.CallBack.Interfaces.INotificationServices" name="NetTcpBinding_INotificationServices">
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

When working with distributed application, securing communication between the client and the service is a very vital issue. Windows Communication Foundation provides the facility of transfer security which is responsible for ensuring the integrity and confidentiality of service messages, and also responsible for providing authentication. Transfer security in WCF is achieved through the use of either transport security or message security. Transport-layer security provides integrity and confidentiality, while message-layer security provides a variety of passes which are not possible with transport security mechanisms. When using transport security, user credentials are transport-dependent, which allows fewer authentication options compared to message security. And each transport protocol has its own way for passing credentials and handling message guard. But SSL is the most common approach for encrypting and signing the contents sent over HTTPS. Here I will explain how to configure WCF Services and Clients to communicate over HTTPS by using self-signed Certificates.

When I intend to write any technical stuff, my intention always goes to start with a very simple example as well as gives an overview with the necessary things related to it. There is no difference this time as well. So for the purposes of this blog post I am going to organize it with Self-Signed Certificate Creation, Services and its Configuration, Clients and its Configuration. Please be noted that I would like to use custom binding for the code examples given here.

Self-Signed Certificate Creation

In Certificate based communication, we need to use two certificates for the client and server to authenticate each other. To make those certificates I would like to use the “MakeCert.exe” utility with the following arguments

makecert -pe -ss My -sr LocalMachine -a sha1 -sky exchange -n CN=ServerCertificate

makecert -pe -ss MY -sr LocalMachine -a sha1 -sky exchange -n CN=ClientCerttificate

Image

The complete specification of this is available here

Now,

First bring up the Microsoft Management Console by launching mmc.exe which allows us to browse the local machine’s cache of certificates.

Image

Next add the Certificates MMC Snap-in and select Computer account

Image

Navigate to the “Personal” node to see ClientCertificate and ServerCertificate.

Image

It is also required to export the certificates from the certificate store and import the copies of those into the TrustedPeople store so that WCF can find them for validation purposes.

Since I would like to use IIS hosting, we need to configure IIS for https. To do that,

  • Open IIS Manager
  • Select Default Web site and open its property window
  • Click the Edit Binding.

Image

Click Add and select HTTPS and then Select ServerCertificate that you have created earlier

Image

Okay done .Everything is okay now.

Service and its Configuration

I have used here very simple service which is “Feedback” service. The service contract looks like,

[ServiceContract]
public interface IFeedback
{
    [OperationContract]
    string GiveFeedback(string question);
}

With such a simple contract the implementation is just straight forward

public class Feedback : IFeedback
{
    public string GiveFeedback(string question)
    {
        var feedback = question + " : This is very funny stuff";
        return feedback;
    }
}

The configuration file for this Service is given below,

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service
      name="Rashim.RND.WCF.SecureCommunication.WcfService.Feedback"
      behaviorConfiguration="MyCustomBehavior">
        <endpoint address=""
        binding="customBinding"
        contract="Rashim.RND.WCF.SecureCommunication.Interfaces.IFeedback"
        bindingConfiguration="MyCustomBinding"/>
        <endpoint
        address="mex"
        binding="mexHttpsBinding"
        contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyCustomBehavior">
          <serviceMetadata httpsGetEnabled="true" />
          <serviceCredentials>
            <clientCertificate>
              <authentication
              certificateValidationMode="PeerTrust"
              trustedStoreLocation="LocalMachine" />
            </clientCertificate>
            <serviceCertificate
            findValue="ServerCert"
            x509FindType="FindBySubjectName"
            storeLocation="LocalMachine"
            storeName="My"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="MyCustomBinding"
        closeTimeout="00:20:00"
        openTimeout="00:20:00"
        receiveTimeout="00:20:00"
        sendTimeout="00:20:00">
          <security
          authenticationMode="CertificateOverTransport"
          requireSecurityContextCancellation="true"/>
          <httpsTransport/>
        </binding>
      </customBinding>
    </bindings>
    <serviceHostingEnvironment
    multipleSiteBindingsEnabled="false" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="false" />
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

To get a better idea about the different sections of this configuration file I would like to explain it a bit more,

<services>
  <service
  name="Rashim.RND.WCF.SecureCommunication.WcfService.Feedback"
  behaviorConfiguration="MyCustomBehavior">
    <endpoint
    address="" binding="customBinding"
    contract="Rashim.RND.WCF.SecureCommunication.Interfaces.IFeedback"
    bindingConfiguration="MyCustomBinding"/>
    <endpoint address="mex"
    binding="mexHttpsBinding"
    contract="IMetadataExchange" />
  </service>
</services>

In this above section we see that Custom behavior configuration and custom binding configuration has been used.

The custom behavior section is given below,

<behavior name="MyCustomBehavior">
  <serviceMetadata httpsGetEnabled="true" />
  <serviceCredentials>
    <clientCertificate>
      <authentication
      certificateValidationMode="PeerOrChainTrust"
      trustedStoreLocation="LocalMachine" />
    </clientCertificate>
    <serviceCertificate
    findValue="ServerCert"
    x509FindType="FindBySubjectName"
    storeLocation="LocalMachine"
    storeName="My"/>
  </serviceCredentials>
</behavior>

Here clientCertificate describes an X.509 certificate which has been used to validate a client to a service. At the same time, serviceCertificate specify an X.509 certificate that will be used to authenticate the service to clients. There is a detail explanations about this has been given here [^] [^].

And the custom binding configuration section is,

<binding name="MyCustomBinding"
closeTimeout="00:20:00"
openTimeout="00:20:00"
receiveTimeout="00:20:00"
sendTimeout="00:20:00">
  <security
  authenticationMode="CertificateOverTransport"
  requireSecurityContextCancellation="true">
  </security>
  <sslStreamSecurity requireClientCertificate="true"/>
  <httpsTransport/>
</binding>

We know that, WCF provides several modes by which clients and services verify to each other. We can create binding for these authentication modes through configuration or by code. Here I have used CertificateOverTransport which means the service is valid using an X.509 certificate at the transport layer.  And requireSecurityContextCancellation specifies whether security context should be cancelled and terminated when it is no longer required.

That’s it.Now try to  browse https://localhost/Feedback/Feedback.svc and you will get the following page

Image

Client and its Configuration

Once services have been implemented, the implementation of client is pretty simple. The client code has been given below,

System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;

        var channel = new ChannelFactory<IFeedback>("FeedbackEndpoint");

        var client = channel.CreateChannel();

        var input = Console.ReadLine();

        while (input != null && input.ToLower() != "exit")
        {
            var feedback = client.GiveFeedback(input);
            Console.WriteLine(feedback);
            input = Console.ReadLine();
        }

The code above will trust any security certificate handed back from the server since it bypasses the SSL certificate validation. As the certificate I have used here is a self-signed certificate and it is not signed by a trusted CA, I need to make own validation logic to check for it .

So the configuration file for the client is,

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="MyCustomBinding">
          <security authenticationMode="CertificateOverTransport"/>
          <textMessageEncoding />
          <httpsTransport />
        </binding>
      </customBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyCustomBehavior">
          <clientCredentials>
            <clientCertificate
            findValue="ClientCert"
            storeLocation="LocalMachine"
            storeName="My"
            x509FindType="FindBySubjectName" />
            <serviceCertificate>
              <authentication
              certificateValidationMode="PeerOrChainTrust"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <client>
      <endpoint
      address="https://localhost/FeedbackService/Feedback.svc"
      binding="customBinding"
      bindingConfiguration="MyCustomBinding"
      contract="Rashim.RND.WCF.SecureCommunication.Interfaces.IFeedback"
      behaviorConfiguration="MyCustomBehavior"
      name="FeedbackEndpoint"/>
    </client>
  </system.serviceModel>
</configuration>

That’s it. I think this would help you while you will be working with the Certificate based communication.

Source code is available here.


%d bloggers like this: