Sending messages between program instances

  • Thread starter Thread starter rwakelan
  • Start date Start date
R

rwakelan

I am trying to create a program that implements the Singleton pattern.
If another instance of the program is created, I want to send the
information to the first instance and then close the new instance. I
have a couple of different ways of keeping the second instance from
opening up and they seem to work well. However, I am getting stuck
whenever I try to send information from the second instance to the
first instance. I have tried to set up .NET remoting using
IrcServerChannel and IrcClientChannel, but I am not sure this is right
because everything I see uses an external object and that doesn't make
sense for what I am doing. Is there any way to do what I need to do?
 
A bit like this? Rather that a Mutex (which would also work), this relies on
only being able to bind one server to the port.

using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels.Ipc;

class Program
{
static void Main(string[] appArgs)
{
string message = string.Join("|", appArgs);
if (RemoteMessage.StartServer())
{ // new instance; start main app

RemoteMessage.MessageReceived += delegate(object sender,
RemoteMessage.RemoteMessageEventArgs remoteArgs)
{
Console.WriteLine("Received: " + remoteArgs.Message);
};
Console.WriteLine("Startup: " + message);
Console.WriteLine("Press [Return] to end server");
Console.ReadLine();
}
else
{ // already running; forward the message
RemoteMessage.SendMessage(message);
Console.WriteLine("Forwarded: " + message);
}
}

}

public static class RemoteMessage
{

public static event EventHandler<RemoteMessageEventArgs>
MessageReceived;

private static void OnMessageReceived(string message)
{
EventHandler<RemoteMessageEventArgs> handler = MessageReceived;
if (handler != null)
{
handler(typeof(RemoteMessage), new
RemoteMessageEventArgs(message));
}
}

public class RemoteMessageEventArgs : EventArgs
{
public readonly string Message;
public RemoteMessageEventArgs(string message)
{
Message = message;
}
}
public sealed class RemoteAgent : ContextBoundObject
{
public void ProcessMessage(string message)
{
RemoteMessage.OnMessageReceived(message);
}
}

private readonly static object _syncLock = new object();
private static object SyncLock { get { return _syncLock; } }
private static int _port = 32561;
public static int Port
{
get { lock (SyncLock) { return _port; } }
set { lock (SyncLock) { _port = value; } }
}

private static string _app = "Anon";
public static string App
{
get { lock (SyncLock) { return _app; } }
set
{
if (value == null) throw new ArgumentNullException("App");
lock (SyncLock)
{
_app = value;
}
}
}

public static bool StartServer()
{
try
{
int port = Port;
string app = App;
if (ChannelServices.GetChannel("ipc") == null)
{
ChannelServices.RegisterChannel(new IpcChannel("127.0.0.1:"
+ port.ToString()), false);
}

WellKnownServiceTypeEntry serviceType = new
WellKnownServiceTypeEntry(typeof(RemoteAgent), app,
WellKnownObjectMode.Singleton);
RemotingConfiguration.RegisterWellKnownServiceType(serviceType);

return true;

}
catch (Exception e)
{
return false; // server already running
}

}

public static void SimulateMessage(string message)
{
OnMessageReceived(message);
}

public static bool SendMessage(string message, string server, string
app, int port)
{
bool localChannel;
IChannel channel = ChannelServices.GetChannel("ipc");
localChannel = channel == null;

string uri = string.Format("ipc://{2}:{0}/{1}", port, app, server);

if (localChannel)
{
channel = new IpcChannel();
ChannelServices.RegisterChannel(channel, false);
}
try
{
if
(RemotingConfiguration.IsWellKnownClientType(typeof(RemoteAgent)) == null)
{
WellKnownClientTypeEntry serviceType = new
WellKnownClientTypeEntry(typeof(RemoteAgent), uri);
RemotingConfiguration.RegisterWellKnownClientType(serviceType);

}
RemoteAgent agent =
(RemoteAgent)Activator.GetObject(typeof(RemoteAgent), uri);
try
{
agent.ProcessMessage(message);
return true;
}
catch
{
return false;
}
}
finally
{
if (localChannel)
{
ChannelServices.UnregisterChannel(channel);
}
}
}
public static bool SendMessage(string message)
{
return SendMessage(message, "127.0.0.1", App, Port);
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top