WCF

Using MSMQ

Microsoft Windows Message Queuing is the easy way to communicate with application programs quickly and reliably by sending and receiving messages. Messaging provides a flexible and powerful mechanism for inter-process communication between the components of server-based applications.

What are Volatile and Dead letter queues?

Volatile Queues: There are scenarios in the project when you want the message to deliver in proper time. The timely delivery of message is very more important and to ensure they are not lost is important too. Volatile queues are used for such purposes.

Dead-Letter Queues: Queues are needed so that client and server are not required to run at the same time when the message is sent. When a message lies inside a queue for a long time on the server and becomes invalid after some time period, then such messages are not to be sent to the client. All these messages are sent to dead-letter queue. Therefore, dead-letter queues are responsible for storing messages that fail timely delivery


The following code sample demonstrates creating a durable service.
C#
[ServiceContract()]
public interface IService1
{
    [OperationContract]
    string MyOperation1(string myValue);
    [OperationContract]
    string MyOperation2(DataContract1 dataContractValue);
}
[DurableService(MyPersistenceProvider)]
public class service1 : IService1
{
    [DurableOperation]
    public string MyOperation1(string myValue)
    {
        Return "Hello: " + myValue;
    }
    [DurableOperation]
    string MyOperation2(DataContract1 dataContractValue)
    {
        return "Hello: " + dataContractValue.DataName;
    }
}
[DataContract]
public class DataContract1
{
    string dataNameValue;
    [DataMember]
    public string DataName
    {
        get { return dataNameValue; }
        set { dataNameValue = value; }
    }
}

WCF defines four types of contracts

Service Contract
Data Contract
Message Contract
Fault Contract

Service Contract

Service contract describes the operations, or methods, that are available on the service endpoint, and exposed to the outside world. A Service contract describes the client-callable operations (functions) exposed by the service, apart from that it also describes.

location of operations, interface and methods of your service to a platform-independent description
message exchange patterns that the service can have with another party. might be one-way/request-reply/duplex

[ServiceContract]
interface ICuboidService
{
    [OperationContract]
    CuboidDetail CalculateDetails2(CuboidInfo cInfo);
}

Data Contract   

In one line, data contract describes the data to be exchanged. it is formal agreement between service and client, that contains information about the data they will be exchanging. the important point, which needs to be mentioned here is that the two parties don’t have to share the same data types to communicate, they only need the share the same data contracts. Data contract defines which parameter & return type will be serialized/de-serialized to and from (Binary <==> XML) in order to be transmitted between one party to another.  Data contracts can be defined by annotating a class, enumeration, or even a structure, but not an interface.

DataContract]    
public class CuboidDetail    
{    
      [DataMember]        public int ID;    
      [DataMember]        public double SurfaceArea;    
      [DataMember]        public double Volume;    
}



Message Contract

WCF uses SOAP message for communication. Most of the time developer concentrates more on developing the DataContract, Serializing the data, etc. Some time developer will also require control over the SOAP message format. In that case WCF provides Message Contract to customize the message as per requirement.

A Message Contract is used to control the structure of a message body and serialization process. It is also used to send / access information in SOAP headers. By default WCF takes care of creating SOAP messages
according to service DataContracts and OperationContracts.


A Message Contract is used to control the structure of a message body and serialization process. It is also used to send / access information in SOAP headers. By default WCF takes care of creating SOAP messages
according to service DataContracts and OperationContracts.




[MessageContract]
public class CuboidDetailResponse
{
    private int m_nID;
    private double m_dblArea;
    private double m_dblVolume;

    [MessageHeader]
    public int ID
    {
get { return m_nID; }
        set { m_nID = value; }
}

    [MessageBodyMember]
    public double SurfaceArea
    {
get { return m_dblArea ; }
        set { m_dblArea = value ; }
}

    [MessageBodyMember]
    public double Volume
    {
get { return m_dblVolume; }
        set { m_dblVolume = value; }
}
}

Fault Contract

Fault Contract provides documented view for error accorded in the service to client. This help as to easy identity the what error has occurred, and where. By default when we throw any exception from service, it will not reach the client side. The less the client knows about what happened on the server side, the more dissociated the interaction will be, this phenomenon (not allowing the actual cause of error to reach client). is known as error masking. By default all exceptions thrown on the service side always reach the client as FaultException, as by having all service exceptions indistinguishable from one another, WCF decouples the client from service.

Using a Custom Proxy
In the previous parts of this chapter, you read about the possible ways you can extend the .NET Remoting Framework using additional custom message sinks. There is another option for changing the default behavior of the remoting system: custom proxy objects. Figure 9-9 shows you the default proxy configuration.


using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;

namespace Client
{
public class CustomProxy: RealProxy
{
String _url;
String _uri;
IMessageSink _sinkChain;

public CustomProxy(Type type, String url) : base(type)
{
_url = url;

// check each registered channel if it accepts the
// given URL
IChannel[] registeredChannels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in registeredChannels )
{
if (channel is IChannelSender)
{
IChannelSender channelSender = (IChannelSender)channel;

// try to create the sink
_sinkChain = channelSender.CreateMessageSink(_url,
null, out _uri);

// if the channel returned a sink chain, exit the loop
if (_sinkChain != null) break;
}
}

// no registered channel accepted the URL
if (_sinkChain == null)
{
throw new Exception("No channel has been found for " + _url);
}
}

public override IMessage Invoke(IMessage msg)
{
msg.Properties["__Uri"] = _url;

// TODO: process the request message

IMessage retMsg = _sinkChain.SyncProcessMessage(msg);

// TODO: process the return message

return retMsg;
}
}
}


No comments:

Post a Comment