Client: Channel Factories and Channels

This topic discusses the creation of channel factories and channels.

Channel Factories and Channels

Channel factories are responsible for creating channels. Channels created by channel factories are used for sending messages. These channels are responsible for getting the message from the layer above, performing whatever processing is necessary, then sending the message to the layer below. The following graphic illustrates this process.

Client Factories and Channels
A channel factory creates channels.

When closed, channel factories are responsible for closing any channels they created that are not yet closed. Note that the model is asymmetric here because when a channel listener is closed, it only stops accepting new channels but leaves existing channels open so that they can continue receiving messages.

WCF provides base class helpers for this process. (For a diagram of the channel helper classes discussed in this topic, see Channel Model Overview.)

The following discussion is based upon the Transport: UDP sample.

Creating a 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 to 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.

The override of OnOpen creates a socket that is used to send messages to this EndPoint.

this.socket = new Socket(  
this.remoteEndPoint.AddressFamily,
  SocketType.Dgram,
  ProtocolType.Udp
);  

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.

this.socket.Close();  
base.OnClose(timeout);  

Implement Send() and BeginSend()/EndSend(). This breaks down into two main sections. First serialize the message into a byte array:

ArraySegment<byte> messageBuffer = EncodeMessage(message);  

Then send the resulting data on the wire:

this.socket.SendTo(  
  messageBuffer.Array,
  messageBuffer.Offset,
  messageBuffer.Count,
  SocketFlags.None,
  this.remoteEndPoint  
);  

See also