我应该在同一台机器上运行的 Firefox 扩展和 C# 代码之间使用哪种 IPC 方法?
Posted
技术标签:
【中文标题】我应该在同一台机器上运行的 Firefox 扩展和 C# 代码之间使用哪种 IPC 方法?【英文标题】:What IPC method should I use between Firefox extension and C# code running on the same machine? 【发布时间】:2009-11-21 00:33:15 【问题描述】:我有一个关于如何构建(新)Firefox 扩展和现有 C# 代码之间通信的问题。
firefox 扩展将使用配置数据并生成其他数据,因此需要从某处获取配置数据并将其输出保存在某处。数据由现有的 C# 代码生成/使用,因此我需要决定扩展应如何与 C# 代码交互。
一些相关因素:
它只在 Windows 上运行,在相对受控的公司环境中。 我在机器上运行了一个 Windows 服务,用 C# 构建。 出于其他原因,将数据存储在本地数据存储(如 sqlite)中会很有用。 数据量低,例如每隔几分钟就有 10kb 的未压缩 xml,而且不是很“健谈”。 数据交换在大部分情况下可以是异步的,如果不是完全同步的话。 与所有项目一样,我的资源有限,所以想要一个相对简单的选项。 它不必是超高性能,但不应增加大量开销。 我正计划在 javascript 中构建扩展程序(尽管如果真的有必要,可以另外说服)我正在考虑的一些选项:
-
使用 XPCOM 到 .NET/COM 的桥接
使用 sqlite db:扩展将从中读取并保存到其中。 c# 代码将在服务中运行,填充数据库,然后处理服务创建的数据。
使用 TCP 套接字在扩展和服务之间进行通信。让服务管理本地数据存储。
我对 (1) 的问题是我认为这会很棘手,而且不是那么容易。但我可能完全错了吗?我看到(2)的主要问题是sqlite的锁定:一次只有一个进程可以写入数据,所以会有一些阻塞。但是,通常拥有一个本地数据存储会很好,因此如果性能影响不是太大,这是一个有吸引力的选择。我不知道 (3) 是特别容易还是特别难……或者对协议采取什么方法:自定义或 http。
对这些想法或其他建议有什么意见吗?
更新:我打算用 javascript 而不是 c++ 构建扩展
【问题讨论】:
您可以添加的另一个选项是内存映射文件。 @R.MartinhoFernandes 没错,但 Pipes 不就是这样吗? MMF 意味着您仍然需要就保留内存的某种方式达成一致,传达该内存的位置,然后确保两个程序都可以访问。此时操作系统存在足够多的潜在问题,因此使用管道等内置机制要容易得多。 【参考方案1】:我个人会使用named pipes 来代替套接字进行通信。它们的开销非常低,并且在 Windows 上非常可靠。
这在 C++ 和 C# 中非常容易使用。
【讨论】:
【参考方案2】:如果您需要任何类型的 RPC,请使用第一个。否则,您会发现自己编写 RPC 语言、验证、构造/解构等,对于本地机器上的某些东西来说有点过火了。
如果你有一个非常被动的插件,最好的选择。第三个组件将两个进程完全解耦,这对很多事情都有好处,包括如上所述的异步、测试、易于实现等。如果你想做大量的消息传递,这可能是一个愚蠢的想法。
可能是大多数事情的最佳选择。从通过 Internet 发送内容的角度来看,TCP/IP 很好,但您并不真正想要两个不同的 IP 地址,也不想搞乱设置网络服务器和可能的端口冲突。管道更有意义,或者其他一些类似的串行通信模型。它解耦得很好,它可以完全异步(TCP/IP 是异步的,普通 HTTP 不是,管道也是),它很容易测试(当然假设你不必编写任何协议),而且它不太关心代码库。这意味着明天,如果您的 C# 后端变成 Ruby 后端或 Python 后端,那么整个事情仍然“正常工作”。它也比 sqlite 好,因为您不必担心使用插件打包整个库和数据库。
第三个选项的唯一缺点是(一个)事情将是异步的,但应该是响应式和主动式的,而 sqlite 不仅允许事情主要是被动的,而且不会通过关闭计算机来分阶段进行一个星期。并且(二)对于 RPC 来说也不是很神奇,如果你想再次这样做,你最终会发明自己的协议或处理诸如 SOAP 和 WSDL 之类的东西。
【讨论】:
【参考方案3】:好吧,如果您打算使用 JavaScript,除了在 C++ 中编写代理组件之外,我看不到其他使用命名管道或其他系统相关通信的方法,这将允许您直接访问 OS API。另一方面,如果您打算将 TCP/UDP 用于 IPC,这对您来说会容易得多,因为 Firefox 提供了您可以从 JavaScript 组件轻松使用的套接字服务。
如果您担心阻塞,您可以使用异步套接字通信或线程服务来避免锁定 Firefox 的 GUI,但请注意,许多对象只能从 Firefox 的主线程访问。
【讨论】:
【参考方案4】:我选择的选项是 #2:使用 sqlite db。主要优点是:
可以在 javascript 中实现 出于其他原因使用 sqlite 数据库 异步通信提高了性能:C# 代码能够缓存 Firefox 扩展所需的所有信息,而不必按需准备。 FF 扩展能够将所有数据保存回 sqlite db,而不需要立即由 C# 代码处理。 单独的层提供了一个很好的测试点,例如可以只运行 FF 代码并在 sqlite 中验证预期结果,而不需要跨 FF 和 C# 运行的测试工具。显然其中一些是依赖于场景的,所以我绝对不会说这是 FF extn 和 C# 服务之间通信的最佳通用选项。
更新:我们最初只使用了一个 sqlite db,然后想要一些同步通信,所以后来从 C# windows 服务中公开了一个 http web 服务,该服务由 FF 扩展调用。此 Web 服务现在被 FF 扩展和其他浏览器扩展所使用。很高兴它是一个网络服务,因为它可以很容易地被不同语言的不同应用程序使用。
【讨论】:
以上是关于我应该在同一台机器上运行的 Firefox 扩展和 C# 代码之间使用哪种 IPC 方法?的主要内容,如果未能解决你的问题,请参考以下文章