Client: Channel Factories and Channels
This topic discusses the creation of 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.
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.)
TheChannelManagerBase class implements CommunicationObject and provides a unified base class for System.ServiceModel.Channels.ChannelFactoryBase and System.ServiceModel.Channels.ChannelListenerBase. The ChannelManagerBase class works in conjunction with ChannelBase, which is a base class that implements IChannel.
The following discussion is based upon the Transport: UDP sample.
Creating a Channel Factory
The UdpChannelFactory derives from ChannelFactoryBase. The sample overrides GetProperty<T> 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
this.socket = new Socket(
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.
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 );