tsJensen

A quest for software excellence...

ASP.NET and IPC Remoting

I'm creating a .NET 2.0 ASP.NET web service as a front end to several Windows Services (also built using .NET 2.0) and want to use IPC since the web service and the Windows Services will be running on the same machine.

I don't want to use XML configuration files. I want to do it in code. It works with a console app to the Windows Service, but the ASP.NET web service blows chunks.

Failed to connect to an IPC port:  Access Denied

Search. Search. Search. One clue about "authorizedGroup" = "Everyone" but no code. Tinker. Stumble. Search. Tinker. Finally. Here's the final result in the Windows Service server:

Dictionary<string, string> props = new Dictionary<string, string>();
props.Add("authorizedGroup", "Everyone");
props.Add("portName", "ServerPortName");
serverChannel = new IpcServerChannel(props, null);
ChannelServices.RegisterChannel(serverChannel, true);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MarshalByRefObjectSubClass),
   "ServerAppName", WellKnownObjectMode.SingleCall);
serverChannel.StartListening(null);

With the client setup like this in the web service:

using System;
using System.Data;
using System.Configuration;
using System.Threading;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using MyRemotingInterfaces;

public class RemotingClientFactory
{
   private static Mutex mut = new Mutex();
   private static WellKnownClientTypeEntry remoteEntry;
   private static IpcClientChannel remoteChannel;
   private static string remoteUrl = "ipc://RemoteExampleRemoteServer/RemoteExampleRemote";

   static RemotingClientFactory() { }

   public static IMyRemoteObject CreateRemote()
   {
      if (remoteChannel == null || remoteEntry == null)
      {
         mut.WaitOne();
         try
         {
            if (remoteChannel == null)
            {
               remoteChannel = new IpcClientChannel();
               ChannelServices.RegisterChannel(remoteChannel, true);
            }
            if (remoteEntry == null)
            {
               remoteEntry =
                 new WellKnownClientTypeEntry(typeof(MyRemotingInterfaces.IMyRemoteObject),
                       remoteUrl);
               RemotingConfiguration.RegisterWellKnownClientType(remoteEntry);
            }
         }
         finally
         {
            mut.ReleaseMutex();
         }
      }
      try
      {
         IMyRemoteObject obj =
          
(IRemoteExampleRemote)Activator.GetObject(remoteEntry.ObjectType, remoteUrl);
         return obj;
      }
      catch(Exception e)
      {
         //TODO log then rethrow
         throw e;
      }
   }
}

And it works like a charm. It's not perfect, I'm sure. But it's a start. And it didn't seem like anyone had or wanted to post their solution to the newsgroups or anywhere else I could find.

Let me know if you find a better way or if this helps you. And good luck.