【发布时间】:2011-08-07 02:42:03
【问题描述】:
我有一个用 C# 编写的现有库,它包装了一个低级别 TCP/IP API,并将来自服务器(专有二进制协议)的消息公开为 .NET 事件。我还提供了对对象的方法调用,该对象处理将方便的 .NET 类型(如 System.DateTime)编组为 API 所需的二进制编码和固定长度结构(用于向服务器传出消息)的复杂性。有相当多的现有应用程序(内部应用程序和第三方使用的)构建在这个 .NET 库之上。
最近,有人与我们接触,他们不想自己做所有抽象 TCP/IP 的繁琐工作,但他们的环境严格非 Windows(我假设 *nix,但我不是 100 % 当然),并且他们已经暗示他们的理想是可以从 Java 中调用的东西。
什么是支持他们的要求的最佳方式,而无需我:
- 现在将代码移植到 Java(包括我们当前 P/Invoke 用于解压缩的非托管 DLL)
- 今后必须维护两个独立的代码库(即两次进行相同的错误修复和功能增强)
我考虑过的一件事是将大部分核心 TCP/IP 功能重写为更跨平台 (C/C++) 的东西,然后将我的 .NET 库更改为在此之上的一个薄层(P/Invoke?),然后在其上也写一个类似的薄 Java 层(JNI?)。
优点:
- 我大部分时间只花一次时间写东西。
缺点:
- 现在大部分代码都将不受管理 - 不是世界末日,但从生产力的角度来看并不理想(对我而言)。
- 更长的开发时间(不能像移植到 Java 一样快地将 C# 套接字代码移植到 C/C++)[这是真的吗?]
- 此时,底层 API 大部分已封装,库非常稳定,因此可能没有太多新开发 - 仅将当前代码移植到 Java 并偶尔需要做一些可能还不错将来会修复错误或公开两次新字段。
- 我现有的客户端应用程序可能不稳定,而它们运行的版本在它们下面发生了巨大变化。 (我突然想到 32/64 位问题、字节顺序问题以及移植期间可能出现的一般错误等)
我简要考虑过的另一个选择是以某种方式将 Mono 安装到 Java,这样我就可以利用我已经拥有的所有现有 C# 代码。尽管对于必须使用它的 Java 开发人员来说,开发人员的体验有多流畅,但我并不太清楚。我很确定大多数代码在 Mono 下应该可以毫无问题地运行(除了解压 P/Invoke,它可能应该只是移植到 C#)。
如果我能提供帮助,我最好不要在我的代码和客户端 Java 应用程序之间添加另一层 TCP/IP、管道等(因此 WCF 到 Java 端的 WS-DeathStar 可能已退出)。我从未使用 Java 进行过任何认真的开发,但我感到自豪的是,该库目前对于第三方开发人员来说是小菜一碟,可以将其集成到他的应用程序中(当然,只要他运行 .NET: )),并且我希望能够为任何想要相同体验的 Java 开发人员保持同样的易用性。
因此,如果有人对我提出的 3 个选项有意见(移植到 Java 并维护两次,移植到 C 并为 .NET 和 Java 编写瘦语言绑定,或者尝试集成 Java 和 Mono),或任何其他我很想听听他们的建议。
谢谢
编辑:在与客户的开发人员直接交谈(即移除损坏的电话 AKA 销售部门)后,要求已经发生了很大变化,以至于这个问题不再适用于我的当前情况。不过,我会留下这个问题,希望我们能提出更多好的建议。
在我的特殊情况下,客户端实际上运行除了 Solaris 之外的 Windows 机器(现在谁不呢?)并且很高兴我们在库之上编写一个应用程序(Windows 服务)并提供更多简化和更小的 TCP/IP API 供他们编写代码。我们会将他们的简单消息翻译成下游系统可以理解的格式,并将传入的响应翻译回给他们使用,以便他们可以继续通过他们的 Java 应用程序与这个下游系统进行交互。
在考虑了几个星期之后回到原来的场景,我确实有更多的 cmets:
如果您事先知道需要支持多种语言/平台,那么基于 C 的可移植库可能会是您的最佳选择。
在 *nix 上,单个进程能否同时托管 Java 运行时和 Mono 运行时?我知道在早期版本的 .NET 中你不能在同一个进程中有两个不同的 .NET 运行时,但我相信他们已经用 .NET 4 解决了这个问题?如果这是可能的,如何在两者之间进行交流?理想情况下,您需要像静态方法调用和委托一样简单的东西来引发响应。
如果在 Java 和 Mono(方法和委托等)之间没有简单的直接接口支持,可以考虑使用带有协议缓冲区的 ZeroMQ 或 Apache Thrift 作为消息格式。由于 ZeroMQ 支持不同的传输,这将在进程内、进程间和网络上工作。
【问题讨论】:
标签: java .net porting code-reuse