Read first previous Post :
How to Implement UDP as a custom WCF transport (1)
Channel Factory and Channel Listener
The next step in writing a custom transport is to create an implementation of IChannelFactory for client channels and of IChannelListener for service channels.
The channel layer uses a factory pattern for constructing channels. WCF provides base class helpers for this process.
- The CommunicationObject class implements ICommunicationObject and enforces the state machine previously described in Step 2.
- The ChannelManagerBase class implements CommunicationObject and provides a unified base class for ChannelFactoryBase and ChannelListenerBase. The ChannelManagerBase class works in conjunction with ChannelBase, which is a base class that implements IChannel.
- The ChannelFactoryBase class implements ChannelManagerBase and IChannelFactory and consolidates the CreateChannel overloads into one OnCreateChannel abstract method.
- The ChannelListenerBase class implements IChannelListener. It takes care of basic state management.
In this sample, the factory implementation is contained in UdpChannelFactory.cs and the listener implementation is contained in UdpChannelListener.cs. The IChannel implementations are in UdpOutputChannel.cs and UdpInputChannel.cs.
The UDP Channel Factory
The UdpChannelFactory derives from ChannelFactoryBase.
** The sample overrides GetProperty
>>>> to provide access to the message version of the message encoder.
** The sample also overrides OnClose
>>>> so that we can tear down our instance of BufferManager when the state machine transitions.
The UDP Output Channel
The UdpOutputChannel implements IOutputChannel.
The constructor validates the arguments and constructs a destination EndPoint object based on the EndpointAddress that is passed in.
this.socket = new Socket(this.remoteEndPoisnt.AddressFamily,SocketType.Dgram, ProtocolType.Udp);
1- The channel can be closed gracefully or ungracefully.
If the channel is closed gracefully the socket is closed and a call is made to the base class OnClose method.
If this throws an exception, the infrastructure calls Abort to ensure the channel is cleaned up.
2- We then implement Send() and BeginSend()/EndSend().
This breaks down into two main sections.
*** First we serialize the message into a byte array.
ArraySegment<byte> messageBuffer = EncodeMessage(message);
*** Then we send the resulting data on the wire.
this.socket.SendTo(messageBuffer.Array, messageBuffer.Offset, messageBuffer.Count,SocketFlags.None,this.remoteEndPoint);
The UdpChannelListener that the sample implements derives from the ChannelListenerBase class.
It uses a single UDP socket to receive datagrams.
The OnOpen method receives data using the UDP socket in an asynchronous loop.
The data are then converted into messages using the Message Encoding Framework.
message = MessageEncoderFactory.Encoder.ReadMessage(new ArraySegment<byte>(buffer, 0, count), bufferManager);
Because the same datagram channel represents messages that arrive from a number of sources, the UdpChannelListener is a singleton listener.
There is, at most, one active IChannel associated with this listener at a time.
The sample generates another one only if a channel that is returned by the AcceptChannel method is subsequently disposed. When a message is received, it is enqueued into this singleton channel.
The UdpInputChannel class implements IInputChannel.
It consists of a queue of incoming messages that is populated by the UdpChannelListener's socket.
These messages are dequeued by the IInputChannel.Receive method.
the Next Post :
How to Implement UDP as a custom WCF transport (3)