What is Channel in WCF?

In Service oriented architecture there are two parties involved, Server and Client .Server and client communicate to each other via Messages. Message travels over the network. For communication; server and client must be agreed upon

  • Format of message
  • Protocol
  • Transport
  • Encoding of the message etc.

Channels are the responsible component of WCF for

  • Creation of consistent message
  • Transport of consistent message.
  • Conversion of Message in wire format

image

The main goal of Channel is to transform message to format understandable by the communication wire and compatible to both server and client and then transport the message over the wire in between client and server.

image

Essentially Channel has to decide about

  • Protocol used in the message
  • Encoding in the message
  • Message is reliable or not
  • Security of the message
  • Transaction of the message

Mainly channel performs two different types of task and on basis of task channel is of two types,

image

Transport channels are responsible to send and receive the message using a transport protocol. WCF supports HTTP, TCP, and MSMQ, Peer to Peer and Named Piped transport protocols.

Protocol channels are responsible to implement and support security, transaction and reliable messaging. These channels transform and modify the message to make it compatible to wire level.

In a communication there may be one or more than one transport and protocol channels. Collections of different channels are called as Channel Stack.

Different channel performs different tasks. For example one protocol channel can secure the message whereas another protocol channel can make message reliable.

In WCF architecture, transport channel always resides at the bottom of channel stack. A usual channel stack can be depicted as below,

image

WCF provides us many readymade channel stacks to do communication between service and client. This WCF provided channel stacks are known as Binding. One channel layer is defined by one Binding Element.

image

You are very much allowed to create your own channel stack if all WCF provided bindings are not meeting your requirement.

Transport protocol of service and client communicates to each other.

image

Transport channel converts messages into bytes or binary to send over the network. Encoding of messages is also done by the transport channels.

I hope you are having basic idea about channel now. Thanks for reading Smile

If you find my posts useful you may like to follow me on twitter http://twitter.com/debug_mode or may like Facebook page of my blog http://www.facebook.com/DebugMode.Net If you want to see post on a particular topic please do write on FB page or tweet me about that, I would love to help you.

Calling One-Way WCF Service using IOutputChannel

Note: This post is inspired by one of the chapter from book Essential WCF. I tried to put the content in my way. Thanks to the original author. I strongly recommend you to read this post http://winterdom.com/2007/08/ioutputchanneloverirequestchannel

One way communication pattern allows client to send message to service and forget. Client doesn’t have to wait for the response.

One way WCF Service can be created as below,


using System.ServiceModel;

namespace WcfService1
{
[ServiceContract]
public interface IService1
{

[OperationContract(IsOneWay=true)]
void  InsertData();
}
}

What all you need to do is to pass parameter to Operation Contract as below,

clip_image001

Service is implemented as below,

namespace WcfService1
{

public class Service1 : IService1
{
public void InsertData()
{
//Insert here
}
}
}

 

In one way communication two interfaces are very important,

clip_image002

These two interfaces are used to send messages between service and client in one way communication pattern.

clip_image003

At the service side we are using basicHttpBinding and this does not support one-way communication. It is made for Request-reply communication pattern. So you may consider using custom binding made on stack of basicHttpBinding.


static CustomBinding CreateOneWayBinding(Binding baseBinding)
{
List<BindingElement> elements  = new List<BindingElement>();
elements.Add(new OneWayBindingElement());
elements.AddRange(baseBinding.CreateBindingElements());
return new CustomBinding(elements);
}

&nbsp;

Above function can be used at WCF client side as well to create custom binding supporting one-way communication.

At client side we can call One-Way WCF Service using IOutputChannel. For that you need to add below references to the client project.

clip_image002[6]

You can create at client side one-way communication supporting custom binding as below,

image

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Client
{
class Program
{
static void Main(string[] args)
{
BasicHttpBinding binding = new BasicHttpBinding();
CustomBinding bindingToprfoemOneWay = CreateOneWayBinding(binding);
BindingParameterCollection parameters = new BindingParameterCollection();
Message message = Message.CreateMessage(MessageVersion.Soap11,"urn:sendmessage");
IChannelFactory<IOutputChannel> factory = bindingToprfoemOneWay.BuildChannelFactory<IOutputChannel>(parameters);
factory.Open();
IOutputChannel channel = factory.CreateChannel(new EndpointAddress("<a href="http://localhost:10828/Service1.svc">http://localhost:10828/Service1.svc</a>"));
channel.Open();
channel.Send(message);
channel.Close();
factory.Close();
Console.ReadKey();
}
}
}

If you are not using custom binding at service side and relying on basicHttpBinding then very likely you will get below exception,

clip_image001[6]

In this way you can make one-way communication call to WCF Service from the client.

I hope this post was useful. Thanks for reading Smile

If you find my posts useful you may like to follow me on twitter http://twitter.com/debug_mode or may like Facebook page of my blog http://www.facebook.com/DebugMode.Net If you want to see post on a particular topic please do write on FB page or tweet me about that, I would love to help you

XmlDictionary and XmlDictionaryString classes to create WCF Message

It is common when you will create Message, you may use below classes

Class Namespace
XmlDictionary System.Xml
XmlDictionaryString System.Xml

Let us investigate purpose of each class one by one.

XmlDictionary class allows us to create a private pair of Key and Value. This key-value pair can be used to represent

  1. Element name
  2. Attribute name
  3. XML namespace declaration.

XmlDictionary class uses XmlDictionaryString class object to create key value pair. If you see below code, we are creating a XmlDictionary object and List of XmlDictionaryString.

 

image

dct is object of XmlDictionary and while adding string value in this it returns XmlDictionaryString object.

 


XmlDictionary dct = new XmlDictionary();
            List<XmlDictionaryString> lstData = new List<XmlDictionaryString>();
            lstData.Add(dct.Add("Bat"));
            lstData.Add(dct.Add("Ball"));
            lstData.Add(dct.Add("Wicket"));
            foreach (var r in lstData)
            {
                Console.WriteLine("Key  = {0}  and Value = {1}", r.Key, r.Value);
            }
            Console.ReadKey(true);


 

If you run above code you will get output as below,

image

We are simply adding returned XmlDictionaryString object to list of XmlDictionaryString.

I hope this post was useful. Thanks for reading Smile

 

Tracing in WCF: Understanding basic steps

Theory behind WCF Tracing is not an exception of classical definition of Tracing. Through Tracing an application provides information about itself. Information may vary from internal state of object to passed input parameter to method. This information should be logged, persisted or saved somewhere.

WCF Tracing can be used for the instrumentation of the WCF Service.

There are essentially four steps involved in WCF Tracing

image

Emitting Trace information from Service

To emit trace information WCF provides different sources. However you have choice to create trace source using TraceSource class as well. You can choose any of WCF Assembly level trace source to emit the tracing information.

WCF Assembly level Trace Sources are as below,

  1. System.ServiceModel
  2. System.ServiceModel.MessageLogging
  3. System.ServiceModel.IdentityModel
  4. System.ServiceModel.Activation
  5. System.Runtime.Serilization
  6. System.IO.Log

Setting the Trace level

You can define the level of messages you want to trace. If you are tracing all level of messages then size of message generated for tracing would be very bulky and it may affect application negatively.

WCF supports below tracing levels

image

Trace level information is set by using the switchValue attribute for trace source.

Configuring the listener

You need to configure a listener to persist the messages at any desired location. There must be at least one listener configured for WCF tracing.

Listener can be configured either

  1. Through code
  2. Or in configuration file.

You can configure listener directly in source element of the configuration.

Note: In further post, I will discuss in detail on configuring the listener.

Enabling Message logging

Last step you need to perform is to enable message logging in configuration. WCF logs message at two levels.

image

Different attributes of Message loggings are as below,

image

Enough of theory Smile Now let us go ahead and capture basic trace in WCF service.

  1. Create a basic WCF Service
  2. Consume service in a client. I am assuming that you are consuming service in a console client.
  3. Open App.config of console client

Emit Trace Information

Add a source in System.Diagostics

image

Set the Trace Level

image

We are setting here trace level to Information and Activity tracing

Configure the Listener

image

We are using listener System.Diagnostics.XmlWriterTraceListener. Trace information would be find at Traces.svclog file under bin/debug folder .

Trace information gets buffered, so to make it visible you need to flush it using below configuration

image

After performing above three steps your System.Diagnostics should look like below,

image

Enable Message Logging

Last step you need to perform is enabling Message logging. Add below diagnostic in System.ServiceModel.

image

Eventually client side App.Config should look more or less like below, Smile


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
      <diagnostics>
        <messageLogging logEntireMessage="true"
                        logMalformedMessages="false"
                        logMessagesAtServiceLevel="false"
                        logMessagesAtTransportLevel="true"
                        maxMessagesToLog="3000"
                        maxSizeOfMessageToLog="2000"/>
      </diagnostics>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:2934/Service1.svc" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
                name="WSHttpBinding_IService1">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel.MessageLogging"
              switchValue="Information, ActivityTracing">
        <listeners>
          <add name="log"
               type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="Traces.svclog"/>
        </listeners>
      </source>
    </sources>
    <trace autoflush ="true"/>
  </system.diagnostics>
</configuration>

After configuring as said above when you run client application you will get a file in

Bin\debug\Traces.svclog

Open above file to view the trace Smile I hope this post was useful. In further post I will take you to dipper in tracing. Thanks for reading Smile

 

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine

Internal classes to understand WCF Message: XmlDictionaryWriter Class

XmlDictionaryWriter class is one of the most important classes to work with Message in WCF. This class is inherited form XmlWriter class. Essentially this takes as Stream as input parameter. This class mainly performs serialization and encoding of the stream to send as Message in WCF.

 

 

image

There are four factory methods of this class being used extensively. Each method has their own uses as of requirement.

image

image

CreateDictionaryWriter method

It takes as input parameter object of XmlWriter. This method is not being used very extensively. This method could be very handy when we do not have any choice but XmlWriter object as input parameter.

 

image

If you see below code, we are creating a stream. Using stream we are creating a XmlWriter object and passing to XmlDictionaryWriter to create object of the same.


using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream stream = new MemoryStream();
            XmlWriter writer = XmlWriter.Create(stream);
            XmlDictionaryWriter dctWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
            Console.WriteLine(dctWriter.ToString());
            Console.ReadKey(true);


        }
    }

}


 

CreateTextWriter method

This method helps us to create text encoded XML. This is overloaded with three different types of input set.

It can take only a Stream to write to. It writes output with default encoding UTF8.

 

image

It can as input Stream to write to and character Encoding of the output

 

image

It can take Stream to write, character encoding of output and a Boolean value. If Boolean input is true then Stream is closed by writer once writing is done. Else Stream will not be closed by the writer.

image

CreateTextWriter supports only,

  1. UTF8 Encoding
  2. UTF 16 little endian
  3. UTF16 big endian

 

We have been doing much of technical talk and I am sure you do not like it Smile so to please you let me show you, how we could use CreateTextWriter class.

In below code we are reading stream and writing using CreateTextWriter .

 


using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream streamToWrite = new MemoryStream();

            using (XmlDictionaryWriter wrt = XmlDictionaryWriter.CreateTextWriter(streamToWrite, Encoding.UTF8, false))
            {
                wrt.WriteStartDocument();
                wrt.WriteElementString("SongName", "urn:Mysong", "F:\\a.wmv");
                wrt.Flush();
            }

            Console.WriteLine("Number Of Bytes wriiten {0} ", streamToWrite.Position);
            Console.ReadKey(true);
            streamToWrite.Position = 0;
            Byte[] bytes = streamToWrite.ToArray();
            Console.WriteLine(bytes.Length);
            Console.ReadKey(true);
            Console.WriteLine(BitConverter.ToString(bytes));
            Console.WriteLine("Data Read from stream : {0}", new StreamReader(streamToWrite).ReadToEnd());
            Console.ReadKey(true);


        }
}
}



On running you will get output as below,

image

If you would have noticed we used empty stream. So as a resultant we are getting 86 bytes written.

CreateMtomWriter method

This method is used to create MTOM-encoded XML.

We can pass Stream to write and other parameters like encoding.

image

This method allows us to pass boundary of MIME type also along with Stream to write.

image

We are just modifying the write method in above code and you can see the change in output behavior as below,



using System;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace XML
{
    class Program
    {

        static void Main(string[] args)
        {


            MemoryStream streamToWrite = new MemoryStream();


            using (XmlDictionaryWriter wrt = XmlDictionaryWriter.CreateMtomWriter(streamToWrite,
                                                                                  Encoding.UTF8,
                                                                                  1000,
                                                                                  "startinfo",
                                                                                  "Boundary",
                                                                                  "urn:stratUri",
                                                                                  false,
                                                                                  false))
            {
                wrt.WriteStartDocument();
                wrt.WriteElementString("SongName", "urn:Mysong", "F:\\a.wmv");
                wrt.Flush();

            }

            Console.WriteLine("Number Of Bytes wriiten {0} ", streamToWrite.Position);

            streamToWrite.Position = 0;
            Byte[] bytes = streamToWrite.ToArray();


            Console.WriteLine(BitConverter.ToString(bytes));
            Console.WriteLine("Data Read from stream : {0}", new StreamReader(streamToWrite).ReadToEnd());
            Console.ReadKey(true);


        }}}




Expected output you would get as below,

image

I hope this post was useful. I am taking a break here. In next post we will see CreateBinaryWriter method. Thanks for reading Smile

Internal classes to understand WCF Message: XmlDictionary Class

In last post we discussed the way we could create WCF Message. If you go back and reexamine CreateMessage() function , you will find this function is overloaded with 11 different set of inputs.

It is common when you will create Message, you may use XmlDictionary class.

XmlDictionary class allows us to create a private pair of Key and Value. This key-value pair can be used to represent

  • Element name
  • Attribute name
  • XML namespace declaration.

XmlDictionary class uses XmlDictionaryString class object to create key value pair. If you see below code, we are creating a XmlDictionary object and List of XmlDictionaryString.

 

image

dct is object of XmlDictionary and while adding string value in this it returns XmlDictionaryString object.

 


XmlDictionary dct = new XmlDictionary();
            List<XmlDictionaryString> lstData = new List<XmlDictionaryString>();
            lstData.Add(dct.Add("Bat"));
            lstData.Add(dct.Add("Ball"));
            lstData.Add(dct.Add("Wicket"));
            foreach (var r in lstData)
            {
                Console.WriteLine("Key  = {0}  and Value = {1}", r.Key, r.Value);
            }
            Console.ReadKey(true);


 

If you run above code you will get output as below,

image

We are simply adding returned XmlDictionaryString object to list of XmlDictionaryString.

I hope now you have understanding of XmlDictionary class. In next post we will discuss some other important class required to understand Message in WCF.

Thanks for reading  Smile