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

.NET Remoting Message Redirection Channel Sinks

, 20 Jun 2003
An upper logic layer transparent way to redirect .NET remoting calls, enabling exposure of .NET remoting services behind firewall/NAT, to anywhere.
reachability_demo.zip
reachability_demo
demo
Client
App.ico
bin
Debug
Client.csproj.user
KnownObjects
App.ico
KnownObjects.csproj.user
Server
App.ico
bin
Debug
Server.csproj.user
Reachability.csproj.user
reachability_src.zip
using System;
using System.Collections;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;
using System.Runtime.Remoting.Messaging;
using System.Threading;

namespace Reachability
{
	
	class Semaphore 
	{
		public Semaphore(int maxCount) 
		{
			_maxCount = maxCount;
			_currentCount = 0;
		}

		public void Acquire() 
		{
			lock(this) 
			{
				while (_currentCount >= _maxCount) 
				{
					Monitor.Wait(this, System.TimeSpan.FromSeconds(60));
				}
				++_currentCount;
			}
		}

		public void Release() 
		{
			lock(this) 
			{
				_currentCount--;
				Monitor.PulseAll(this);
			}

		}

		private int _maxCount;
		private int _currentCount;
	}

	public class SyncQueue : Queue
	{
		Semaphore sem;

		public SyncQueue()
		{ 
			sem = new Semaphore(0);
		}

		public override void Enqueue(object obj)
		{
			base.Enqueue(obj);
			sem.Release();
		}

		public override object Dequeue()
		{
			sem.Acquire();
			return base.Dequeue();
		}
	}

	public class Redirector : MarshalByRefObject
	{
		public Redirector()
		{
		}
		public void GetNextRequest(Guid slot, out Message m)
		{
			SyncQueue q = reqs[slot] as SyncQueue;			
			if(q==null)reqs.Add(slot, q=new SyncQueue());
			m = q.Dequeue() as Message;
		}
		public void ReturnResponse(Guid slot, Response r)
		{
			SyncQueue q = resps[slot] as SyncQueue;			
			if(q==null)resps.Add(slot, q=new SyncQueue());
			q.Enqueue(r);
		}
		[Serializable]
		public class Message
		{
			public bool oneway;
			public ITransportHeaders requestHeaders;
			public byte[] requestStream;
			public IPrincipal callerPrincipal;
			public Message(ITransportHeaders requestHeaders, byte[] requestStream, IPrincipal principal, bool oneway)
			{
				this.oneway=oneway;
				this.requestHeaders=requestHeaders;
				this.requestStream=requestStream;
				this.callerPrincipal=principal;
			}
		}
		[Serializable]
		public class Response
		{
			public Response(ITransportHeaders h, Stream s)
			{
				this.responseHeaders=h;
				responseStream = new byte[s.Length];
				s.Read(responseStream, 0, responseStream.Length);
			}
			public ITransportHeaders responseHeaders;
			public byte[] responseStream;
		}
		Hashtable reqs = Hashtable.Synchronized(new Hashtable());
		Hashtable resps = Hashtable.Synchronized(new Hashtable());
		// no longer listening incoming requests.
		public void RevokeDestinationSlot(Guid slot)
		{
			SyncQueue q = reqs[slot] as SyncQueue;	
			q.Enqueue(new object());

			reqs.Remove(slot);
			resps.Remove(slot);
		}
		public void RedirectRequest(Guid slot, bool oneway, ITransportHeaders requestHeaders, byte[] requestStream, out ITransportHeaders responseHeaders, out byte[] responseStream)
		{
			SyncQueue q = reqs[slot] as SyncQueue;		
			if(q==null)reqs.Add(slot, q=new SyncQueue());
			q.Enqueue(new Message(requestHeaders, requestStream, Thread.CurrentPrincipal, oneway));
			
			if(!oneway)
			{
				q = resps[slot] as SyncQueue;			
				if(q==null)resps.Add(slot, q=new SyncQueue());

				Response r = q.Dequeue() as Response;
				responseHeaders = r.responseHeaders;
				responseStream = r.responseStream;
			}
			else
			{
				responseHeaders = null;
				responseStream = null;
			}
		}
	}
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

zhi
Researcher
United States United States
My name is Zhiheng Cao. I major in Eletronics Engineering, in University of Tokyo. I do part time jobs of computer programming and teaching high school students English and Mathematics.
 
CodeProject provided me with valuable information for my programming job many times in the past. I hope I can do my part by providing goodies I have.
 

| Advertise | Privacy | Mobile
Web04 | 2.8.140827.1 | Last Updated 21 Jun 2003
Article Copyright 2003 by zhi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid