简单的跨平台流程来处理Mono中的通信?

时间:2011-03-20 02:08:54

标签: c# mono ipc

我正在开发一个可在Linux,Mac和Windows上运行的Mono应用程序,并且需要应用程序(在单个操作系统上)才能相互发送简单的字符串消息。

具体来说,我想要一个单实例应用程序。如果尝试启动第二个实例,它将向已经运行的单个实例发送消息。

DBus已经出局了,因为我不希望这是一个额外的要求。 套接字通信似乎很难,因为Windows似乎不允许连接权限。 Mono似乎不支持内存映射文件。 Mono似乎不支持命名管道。 似乎在Mono上不支持IPC。

那么,是否有一种简单的方法可以将单个计算机上的字符串消息发送到可在每个操作系统上运行的服务器应用程序,而无需权限或其他依赖项?

4 个答案:

答案 0 :(得分:4)

在我的ubuntu(10.10 mono版本:2.6.7)上,我尝试使用WCF与BasicHttpBinding,NetTcpBinding和NetNamedPipeBinding进行进程间通信。前2个工作正常,对于NetNamedPipeBinding我收到了一个错误:

  

频道类型IDuplexSessionChannel是   不支持

调用ChannelFactory.CreateChannel()方法时。

我也尝试过使用Remoting(这是WCF出来以来的传统技术)和IpcChannel;这个msdn page的示例在我的机器上启动并且没有问题。

我想你不应该在Windows上使用WCF或Remoting时遇到问题,不确定Mac,但是没有任何一个可以测试。如果您需要任何代码示例,请告诉我。

希望这有帮助,尊重

答案 1 :(得分:3)

我在mono-dev邮件列表上写过这个。考虑了几个通用的进程间消息系统,包括DBus,System.Threading.Mutex类,WCF,Remoting,命名管......结论基本上是mono doesn't support Mutex class(适用于线程间,不适用于inter -process)和there's nothing platform agnostic available

我只能想象出三种可能的解决方案。都有它们的缺点。也许有更好的解决方案可用,或者可能只是针对特定目的的更好的解决方案,或者可能存在一些您可以包含在您的应用中的跨平台第三方库(我不会知道。)但这些是迄今为止我能找到的最佳解决方案:

  • 使用独占锁定在已知位置打开或创建文件。 (FileShare.None)。每个应用程序都会尝试打开文件,执行其工作并关闭文件。如果无法打开,请关闭Thread.Sleep(1)并再试一次。这是一种贫民窟,但它可以跨平台工作以提供进程间互斥。
  • 套接字。第一个应用程序侦听localhost,一些高编号的端口。第二个应用程序尝试侦听该端口,无法打开(因为某些其他进程已经拥有它),因此第二个进程向第一个进程发送消息,该进程已在该端口上侦听。
  • 如果您有权访问事务数据库,或者消息传递系统(sqs,rabbitmq等)使用它。
  • 当然,您可以检测到您所使用的平台,然后使用该平台上的任何工作。

答案 2 :(得分:1)

由于您需要IPC的简单原因,我会寻找另一种解决方案。

此代码已确认可在Linux和Windows上运行。也应该在Mac上运行:

    public static IList Processes()
    {
        IList<Process> processes = new List<Process>();
        foreach (System.Diagnostics.Process process in System.Diagnostics.Process.GetProcesses())
        {
            Process p = new Process();
            p.Pid = process.Id;
            p.Name = process.ProcessName;

            processes.Add(p);
        }
        return processes;
    }

只需遍历列表并查找您自己的ProcessName。

要向您的应用程序发送消息,只需使用MyProcess.StandardInput写入应用程序标准输入。这只适用于您的应用程序是GUI应用程序。

如果您遇到问题,那么您可以使用专门的“锁定”文件。使用FileSystemWatcher类可以检查它何时发生更改。这样,第二个实例可以在文件中写入消息,然后第一个实例注意到它发生了变化,并且可以读取文件的内容以获取消息。

答案 3 :(得分:1)

使用两种技术解决了我的问题:一个命名的互斥锁(以便应用程序可以由不同的用户在同一台​​机器上运行),以及一个消息文件上的观察程序。打开并写入文件以进行通信。这是一个用IronPython 2.6编写的基本解决方案:

(mutex, locked) = System.Threading.Mutex(True, "MyApp/%s" % System.Environment.UserName, None)
if locked:
    watcher = System.IO.FileSystemWatcher()
    watcher.Path = path_to_user_dir
    watcher.Filter = "messages"
    watcher.NotifyFilter = System.IO.NotifyFilters.LastWrite
    watcher.Changed += handleMessages
    watcher.EnableRaisingEvents = True
else:
    messages = os.path.join(path_to_user_dir, "messages")
    fp = file(messages, "a")
    fp.write(command)
    fp.close()
    sys.exit(0)