Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Dynamic insertion of a client channel sink provider

, 10 Apr 2003
Workaround to specify a desired channel for connecting to a remote object
abstract_client_formatter_src.zip
Remoting Helper Solution
InterfaceLibrary
App.ico
InterfaceLibrary.csproj.user
Remoting Helper Solution.suo
RemotingClient
App.ico
RemotingClient.csproj.user
RemotingHelper
RemotingHelper.csproj.user
RemotingServer
App.ico
RemotingServer.csproj.user
TestLibrary
TestLibrary.csproj.user
		
The .NET remoting architecture is world-famous for its flexibility and versatility with
limitations rarely found.

Here is one limitation that I came across.



I have two remote services named Knossos and Zakros with channel configuration
entries,

for Knossos:  

		<channel ref="tcp" port="9000" name = "Two way binary tcp channel">
			<clientProviders>
				<formatter ref="binary"/>
			</clientProviders>
			<serverProviders>
				<formatter ref="binary"/>
			</serverProviders>
		</channel>

and for Zacros:

		<channel ref="tcp" port="9000" name = "Two way soap tcp channel">
			<clientProviders>
				<formatter ref="soap"/>
			</clientProviders>
			<serverProviders>
				<formatter ref="soap"/>
			</serverProviders>
		</channel>


Note that the transport is TCP for either service but the formatting is binary for Knossos and
soap for Zakros.


Next comes a client app that can communicate with both Zakros and Knossos. Here is
the channel configuration for the client app, 

for Knossos:
		<channel ref="tcp" port="8000" name="Two way binary client tcp channel">
			<clientProviders>
				<formatter ref="binary"/>
			</clientProviders>
			<serverProviders>
				<formatter ref="binary"/>
			</serverProviders>
		</channel>
		
and for Zakros:
		
		<channel ref="tcp" port="8080" name="Two way soap client tcp channel">
			<clientProviders>
				<formatter ref="soap"/>
			</clientProviders>
			<serverProviders>
				<formatter ref="soap"/>
			</serverProviders>
		</channel>

Note again that the transport is TCP for either but formatting is binary and soap.

The client app can communicate with Knossos using the TCP-binary channel but not with 
Zakros using the TCP-soap channel.

Everything would work just fine by reconfiguring Zakros for an HTTP channel.
But that is not desired.


One possible solution would be to use an abstract client formatter sink, like so.

public class AbstractClientFormatterSinkProvider 
	: IClientFormatterSinkProvider {
	public AbstractClientFormatterSinkProvider() { }
	public AbstractClientFormatterSinkProvider(IDictionary props, ICollection providerData) { }

	IClientChannelSinkProvider _nextSinkProvider;
	public IClientChannelSinkProvider Next {
		get { return _nextSinkProvider; }
		set { _nextSinkProvider = value; }
	}

	IClientChannelSinkProvider _transportSinkProvider;
	public IClientChannelSink CreateSink(
		IChannelSender channel,
		String URL,
		Object remoteChannelData) {

		// first save the transport sink provider
		if(_transportSinkProvider == null)
			_transportSinkProvider = _nextSinkProvider;

		String format = remoteChannelData as String;
		if(format == null)
			throw new Exception("Client formatter specification required.");

		// create the appropriate formatter sink provider
		IClientChannelSinkProvider  formatterSinkProvider= null;
		if(String.Compare(format,"binary", true) == 0)
			formatterSinkProvider = new BinaryClientFormatterSinkProvider();
		else
		if(String.Compare(format,"soap", true) == 0)
			formatterSinkProvider = new SoapClientFormatterSinkProvider();
		else
			throw new Exception("Channel data required.");

		// insert it between this provider and the transport provider
		formatterSinkProvider.Next = _transportSinkProvider;
		_nextSinkProvider = formatterSinkProvider;

		return formatterSinkProvider.CreateSink(channel, URL, null);
	}
}

I can now change the <clientProviders> section like so:

<clientProviders>
	<formatter type="RemotingHelper.AbstractClientFormatterSinkProvider, RemotingHelper"/>
</clientProviders>


And inside the client app the following code connects to the services.

String urlKnossos = "tcp://knossos:9000/KnossosObject.rem";
KnossosObject objKnossos = (KnossosObject)RemotingServices.Connect(
	typeof(KnossosObject), urlKnossos, "binary");
	
String urlZakros = "tcp://zakros:9000/ZakrosObject.soap";
ZakrosObject objZakros = (ZakrosObject)RemotingServices.Connect(
	typeof(ZakrosObject), urlZakros, "soap");	



By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Wytek Szymanski
Web Developer
United States United States
I am a consultant, trainer, software archtect/engineer, since the early 1980s, working in the greater area of Boston, MA, USA.
 
My work comprises the entire spectrum of software, shrink-wrapped applications, IT client-server, systems and protocol related work, compilers and operating systems, and more ....
 
I am currently focused on platform development for distributed computing in service oriented data centers.

| Advertise | Privacy | Mobile
Web03 | 2.8.140718.1 | Last Updated 11 Apr 2003
Article Copyright 2003 by Wytek Szymanski
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid