Channel Sinks in VB.NET

In this article I will explain you about Channel Sinks in VB.NET.
  • 1630

Channel sinks are the means by which messages are passed back and forth between the client and server. A channel sink can be an alternative way to achieve the same end. But sinks are not limited to that single function. The HTTP and TCP channels, provided by .NET, have two default sinks in the sink chain-a formatter and a transport sink. The formatter converts an IMessage into a stream, while the transporter streams the data across the wire. Each does a discrete unit of work and hands the result to the next sink in the chain.

The .NET Framework does not restrict the number of links in a sink chain. The sink chain can be viewed as a functional linked list, rather than a linked list of data. Depending on the problem domain, one to many sinks are plugged into a channel's chain, with each sink addressing a single task. This may include logging, security functions, encryption, or any other task that is required on the route from the transparent proxy to the remote object. To become a member of a sink chain, certain criteria must be met.

All channels are divided into senders and receivers. Receivers are generally servers, while senders are clients. Channel sinks can be seen in the same light. They are connected to a channel by a sink provider, either a System.Runtime.Remoting.Channels.IClientChannelSinkProvider or an IServerChannelSinkProvider.

Listing 25.28: ClientSinkProvider.vb

       
Imports System.Runtime.Remoting.Channels

Public Class ClientSinkProvider
    Implements IClientChannelSinkProvider
    Private m_next As IClientChannelSinkProvider = Nothing
    Public Sub New()
    End Sub
 
    Public Sub New(ByVal props As IDictionary, ByVal provider As ICollection)
    End Sub
 
    Public Function CreateSink(ByVal sender As IChannelSender, ByVal url As String, ByVal channelData As Object) As
   
IClientChannelSink
        Dim sink As IClientChannelSink = Nothing
 
        If m_next IsNot Nothing Then
            sink = m_next.CreateSink(sender, url, channelData)
        End If
 
        If sink IsNot Nothing Then
            sink = New ClientSink(sink)
        End If
 
        Return (sink)
    End Function
 
    Public Property [Next]() As IClientChannelSinkProvider
        Get
            Return (m_next)
        End Get
        Set(ByVal value As IClientChannelSinkProvider)
            m_next = value
        End Set
    End Property
End Class

Deriving from the IClientChannelSinkProvider interface, described in Listing 25.28, requires implementing the CreateSink method and the Next property. The server provider code, not shown, in ServerSinkProvider.vb is the same, except for an additional method, GetChannelData(), which has a System.Runtime.Remoting.Channels.IChannelDataStore parameter.

Notice in CreateSink() that if there is a next provider, its CreateSink() is called before the current provider instantiates its sink. In other words, the last provider is the first to create an actual sink and starts the process where the sinks are chained together. It is also evident that as soon as the provider creates its sink, it could be a candidate for disposal, as it has no knowledge of the sink once instantiation is complete.

The order in which providers are attached to a channel determines the order of the sink chain. On the server, the first sink must be the transport sink, and the last must the formatter sink. On the client the order is reversed. If the order is incorrect, results are unpredictable! Sink providers are attached to a channel via a configuration file or programmatically. The order of creation will be clearer with some example code. (See Listing 25.29.)

Listing 25.29: SinkClient.cs
       
        Dim channelData As New Hashtable()
        Dim properties As New Hashtable()
        Dim providerData As New ArrayList()
        Dim clientProvider As ClientSinkProvider = Nothing
        Dim serverProvider As ServerSinkProvider = Nothing
        Dim clientFormatter As SoapClientFormatterSinkProvider = Nothing
        Dim serverFormatter As SoapServerFormatterSinkProvider = Nothing
        Dim http As MyHttpChannel = Nothing
       
clientFormatter = New SoapClientFormatterSinkProvider(properties, providerData)
        clientProvider = New ClientSinkProvider(properties, providerData)
        clientFormatter.[Next] = clientProvider
        serverProvider = New ServerSinkProvider(properties, providerData)
        serverFormatter = New SoapServerFormatterSinkProvider(properties, providerData)
        serverProvider.[Next] = serverFormatter
        http = New MyHttpChannel(channelData, clientFormatter, serverProvider)       

The client creates the SOAP formatter and then the customized provider, which is assigned to the clientFormatter.Next property. The server's order of creation and assignment is reversed. Because MyHttpChannel inherits from HttpChannel, both sender and receiver sinks are required. During construction of the channel, the transport sinks are created and placed in the appropriate position in their respective chains.

Listing 25.30: Shared.config

<?
xml version="1.0" ?>
<
configuration>
          <
system.runtime.remoting>
                   <
channels>
                             <
channel id="http"
                            
type="CustomSinkLib.MyHttpChannel, CustomSinkLib">
                             </
channel>
                   </
channels>
                   <
channelSinkProviders>
                             <
clientProviders>
                                      <
formatter id="soap"
                                     
type="System.Runtime.Remoting.Channels.SoapClientFormatterSinkProvider,System.Runtime.Remoting"/>
                                      <
provider id="custom" type="CustomSinkLib.ClientSinkProvider, CustomSinkLib"/>
                             </
clientProviders>
                             <
serverProviders>
                                      <
formatter id="soap"
                                     
type="System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider,System.Runtime.Remoting"/>
                                      <
provider id="custom" type="CustomSinkLib.ServerSinkProvider, CustomSinkLib"/>
                             </
serverProviders>
                   </
channelSinkProviders>
          </
system.runtime.remoting>
</
configuration>

The server and client configuration files are shown in Listings 25.31 and 25.32, while a common configuration file is shown in Figure 25.30. The server's provider is listed ahead of the formatter. Not shown, but present nonetheless, is the transporter. The Http and Tcp namespaces supply a client transport sink provider and transport sink as private classes in System.Runtime.Remoting.dll. It is worth noting that the Http and Tcp servers don't have a transport sink provider, simply a transport sink, which has the variable name transportSink.

Listing 25.31: SinkServerExe.exe.config


<?
xml version="1.0" ?>
<
configuration>
          <
system.runtime.remoting>
                   <
application>
                             <
service>
                                      <
wellknown type="SimpleObjectForSinkLib.SimpleObject, SimpleObjectForSinkLib"
                                       
mode="Singleton" objectUri="Simple"/>
                             </
service>
                             <
channels>
                                      <
channel ref="http" port="1234">
                                                <
serverProviders>
                                                          <
provider ref="custom"/>
                                                          <
formatter ref="soap"/>
                                                </
serverProviders>
                                      </
channel>
                             </
channels>
                   </
application>
          </
system.runtime.remoting>
</
configuration>

Conclusion

Hope this article would have helped you in understanding Channel Sinks in VB.NET. Remaining part of this article you will see in my next article.

Categories

More Articles

© 2020 DotNetHeaven. All rights reserved.