2路跨进程通信

Posted

技术标签:

【中文标题】2路跨进程通信【英文标题】:2-way Cross Process Communication 【发布时间】:2011-10-04 01:17:04 【问题描述】:

我正在做一个项目,我想要一个像 System 这样的插件沙箱,但是我在解决 2-Way 实时跨进程通信时遇到了问题。起初我想到了 WCF,因为它可以传递对象元数据,但很快意识到 WCF 的服务客户端模型会带来问题。但在我提出所有想法和问题之前,我已经计划好了。

我想要一个宿主应用程序来完成大部分工作,让我们调用这个host.exe,host.exe将宿主程序的主要应用程序逻辑,以及启动,执行和杀死插件。插件将通过插件代理托管,该代理将通过 MEF 托管它们,因此我们将其称为 proxy.exe。 proxy.exe 将加载插件 dll 并将它们托管在一个隐蔽的环境中,该环境将隔离故障,如果插件失败,它将终止代理而不是应用程序。主机和代理需要在两个方向上实时通信,因为会有多个代理主机,所以最好能够传递对象数据。

这就是我想要的基本概念。我在想几种方法来做到这一点。第一个是 WCF,但是我认为 WCF 的工作方式即使不是不可能,服务的服务器也很难向客户端发送请求/命令。下一个想法是什么使用 TCP,并让主机成为 TCP 服务器并开发一个我可以用来通信的消息传递协议,但这会带来一个问题,因为我没有 WCF 元数据的奢侈和传递复杂的类信息会快疯了。

通过我所有的研究,我提出了一个又一个问题,如果有人能够提出解决这个问题的方法,我将不胜感激。谢谢。

【问题讨论】:

您将如何帮助您?您真的认为使用几个代码示例就可以解决您的问题吗? 你说的是IPC吗?那么,你就不需要WCF了,WCF不是实时的进程间通信服务,使用实时的基于IPC的客户端-服务器技术。 @Artur Mustafin,我只是想对我迄今为止的计划提出想法和反馈。是的,我知道 WCF 不是实时的。这是我正在考虑的一个选项。虽然我没有代码,但我不想要代码,只是想法和反馈,谢谢。 您可能对托管插件框架感兴趣:msdn.microsoft.com/en-us/library/bb384200.aspx 使用 ZeroMQ 之类的东西怎么样? 【参考方案1】:

我的解决方案可能是远程处理。我不知道 WCF 是否也这样做。但是可以使用文本配置远程处理,并且可以将服务器设置为随意远程到对象。

我想提前警告你。我提到的项目是很久以前的,所以这可能是过时的信息(WCF 可能会做同样的事情,也可能不会,我的公司不需要我做任何 WCF 工作。)

我将我的对象从客户端远程传输到服务器。我会运行服务器(实际上是在单独的机器上)然后使用 tcp 远程处理,我想要的所有对象都将被声明到该应用程序中。

现在是有趣的部分。该远程对象使用非远程委托对象。我会初始化对象(远程),然后服务器会创建它。然后我会在本地初始化另一个(接口类型)对象并将其附加到远程对象。

当远程对象想要与我通信时,它会向我发送可序列化的信息,我会将其构造成更多的对象或命令。无论需要什么......(可能是更远程的对象)

无论如何。一台服务器和多个远程对象将通过 CommonInterface.dll 来回发送,其中定义了所有标准接口对象。

出于所有意图和目的,这是一个盲目的插件设置,只要接口匹配,任何想要从我的服务器获取信息的应用程序都可以实现和处理它们的类。 (带有可序列化的命令数据)

如果插件(客户端)崩溃,那么应用程序(服务器)就不会受到影响。它只会将与该插件的所有通信包装在 try catch 中,并且远程对象将有某种时间来生存或 ping 样式的释放机制。

我真的不知道沙盒会是什么样子,但这可能会满足您的要求。

这是一个 .net 远程聊天服务器。

http://www.codeproject.com/KB/IP/dotnetchatapplication.aspx

这与我第一次使用远程处理构建的项目类型相同。我将它演变成我的服务器插件架构。我使用和你使用的区别在于服务器是我的客户端是使用服务器的主应用程序,而你的服务器将是允许多个客户端插入的主应用程序。

【讨论】:

远程处理已被 WCF 弃用。 谢谢,这与我的想法很相似,而且似乎可行。我只需要想办法将信息序列化成我可以处理的方式,然后我就可以设置了,非常感谢!【参考方案2】:

在我看来,我建议您使用不同的应用程序域、使用接口与插件通信以及真正的代理对象引用。不要使用不同的进程,可以通过应用域隔离实现插件隔离,因为除非指定,否则异常不会跨越应用域边界。

作为替代方案,您可以使用已弃用的技术(如 .NET Remoting)进行自定义编组和透明代理对象创建。

在我看来,WCF 太重,离实时处理太远了

【讨论】:

是的,我查看了 AppDomains,但加载和卸载似乎更麻烦,这是值得的,而且从我阅读的内容来看,对应用程序的引用从未真正被收集。因此,如果我在哪里编译一个新对象来加载和卸载旧对象,它永远不会真正被卸载。 当插件在其创建的线程中出现异常时,其应用程序域会崩溃,并且 .NET 会在任何应用程序域崩溃时终止整个进程。这样宿主也被杀死了。需要进程隔离来防止插件的侧线程中出现未处理的异常。【参考方案3】:

进程间通信 (IPC)。可能应该称为跨进程通信 (CPC) 是已知的 MS/Windows 特定概念。

更多信息here

过去我使用过 RPC 和 Windows Pipes(在 SQL Server 中也用于传输大型数据集/结果)

您总是可以尝试另一种通信方法,WCF、套接字、Pub/Sub 消息传递;例如,TibcoRv(本地会绕过套接字)。 我觉得这些有点矫枉过正。但可能非常适合您的要求。

【讨论】:

以上是关于2路跨进程通信的主要内容,如果未能解决你的问题,请参考以下文章

Android跨进程通信Binder机制与AIDL实例

Android跨进程通信Binder机制与AIDL实例

Android 跨进程通信-从源码分析AIDL跨进程通信实现

跨进程通信之Messenger

WPF怎么能跨进程通信

Android Framework实战开发视频--跨进程通信之Unix Socket通信