简体   繁体   English

IPC with gui(Java和Native code)

[英]IPC with gui (Java & Native code)

My application is composed of 2 parts - 我的申请由两部分组成 -

Some GUI logics in Java. Java中的一些GUI逻辑。 Native code (mainly Delphi) - the GUI implementation itself. 本机代码(主要是Delphi) - GUI实现本身。

Java uses the native code for trivial operations such as opening windows and responding to user-input events - the implementation is done via JNI. Java使用本机代码进行简单的操作,例如打开窗口和响应用户输入事件 - 实现是通过JNI完成的。

I'm interested in dividing both sides to different processes - What would be the best way to implement IPC between them without hanging the gui? 我有兴趣将双方分成不同的流程 - 在不挂gui的情况下,在它们之间实施IPC的最佳方法是什么? I'm leaning towards TCP sockets or shared memory, but before I dive into this I'd love to hear some input. 我倾向于TCP套接字或共享内存,但在我深入研究之前,我很乐意听到一些意见。 Performance and a simple implementation are my main concerns. 性能和简单的实现是我主要关注的问题。

Thanks in advance. 提前致谢。

If your problem is about memory consumption 如果您的问题是关于内存消耗

If you're running short of RAM (as suggested by your comments - but you should have better written this in your main question: the more details you give, the better answers you get). 如果你的RAM不足(正如你的评论所暗示的那样 - 但你应该在你的主要问题中写得更好:你提供的细节越多,得到的答案就越好)。

Why are you mixing Java and Delphi? 你为什么要混用Java和Delphi? Java is probably not a good candidate do handle more than 1 GB of memory, due to its higher memory consumption for common tasks, and its internal GC. Java可能不适合处理超过1 GB的内存,因为它对于常见任务和内部GC具有更高的内存消耗。 Even if you run the JVM in 64 bit, you'll face new scaling problems: you should have to write very specific code to handle huge memory with Java. 即使你以64位运行JVM,你也会遇到新的扩展问题:你应该编写非常具体的代码来处理Java的大量内存。

To be fair, the problems doesn't come from Delphi, but from the Java memory consumption. 公平地说,问题不是来自Delphi,而是来自Java内存消耗。 Therefore, IMHO you should better code your data layer in native code. 因此,恕我直言,你应该更好地用本机代码编码你的数据层。 Java is potentially increasing your problems. Java可能会增加您的问题。

You could either: 你可以:

  • Use the Free Pascal Compiler to compile a 64 bit library from Delphi code, then call it from you main 32 bit Delphi application or from Java using JNI using a Memory Mapped file as bridge . 使用Free Pascal编译器从Delphi代码编译64位库,然后从主32位Delphi应用程序或使用JNI从Java使用Memory Mapped文件作为桥来调用它。
  • Change the way you access the data. 更改访问数据的方式。 You'll probably won't need to have all those GigaBytes of data at once. 您可能不需要同时拥有所有这些GigaBytes数据。 You could lay it on disk, then access to it via indexes, which will remain in RAM. 您可以将它放在磁盘上,然后通过索引访问它,它将保留在RAM中。 If you use Delphi, you should either use your own file handling (you may use something like our BigTable library for storage and indexed access), or use a database (even SQlite3 is able to handle GB of data since its limit is about 140 terabytes, with the power of SQL for retrieving only the data). 如果您使用Delphi,您应该使用自己的文件处理(您可以使用类似我们的BigTable库进行存储和索引访问),或者使用数据库(即使SQlite3能够处理GB数据,因为它的限制大约是140TB ,具有SQL的强大功能,仅用于检索数据)。
  • If you really need to stay in Java , you could probably use some DB instead of plain in-memory structures. 如果你真的需要留在Java中 ,你可能会使用一些DB而不是简单的内存结构。 You can use SQLite from Java, or a pure Java DB. 您可以使用Java中的SQLite或纯Java DB。 I suspect it will reduce your memory consumption. 我怀疑它会减少你的内存消耗。

The main approach is: only keep in memory what is needed, and work with Map/Reduce algorithms or some kind of indexes. 主要方法是:只在内存中保留所需内容,并使用Map / Reduce算法或某种索引。

If your problem is mixing GUI between Java and Delphi 如果您的问题是在Java和Delphi之间混合使用GUI

From my experiment, this could be difficult, because JNI tends to use its own threads, and the VCL expect all its process to be run in the main thread. 从我的实验来看,这可能很难,因为JNI倾向于使用自己的线程,而VCL期望它的所有进程都在主线程中运行。

So you could either: 所以你可以:

  1. Create some Delphi methods, running the VCL Synchronize method when called from the JNI to update the screen. 创建一些Delphi方法,在从JNI调用时运行VCL Synchronize方法来更新屏幕。
  2. Rely on Windows GDI messages communication, ie create your own WM_USER* handler in the Delphi code, then refresh the screen content from you Java code just by sending some low-level PostMessage or SendMessage API. 依靠Windows GDI消息通信,即在Delphi代码中创建自己的WM_USER *处理程序,然后通过发送一些低级PostMessage或SendMessage API从您的Java代码中刷新屏幕内容。 By design, this will be thread-safe. 按照设计,这将是线程安全的。
  3. Use a stateless approach: I like it very much. 使用无状态方法:我非常喜欢它。 Just like in HTTP, you User Interface will act as a Client, and will ask periodically the Data layer (acting as a Server) for refreshed data. 就像在HTTP中一样,用户界面将充当客户端,并定期询问数据层(充当服务器)以获取刷新的数据。 All this process will remain in the main thread, and could be easily made via a Timer. 所有这些过程都将保留在主线程中,并且可以通过Timer轻松完成。 With a timer, a 500 ms period for each refresh is enough, and your main application will remain reactive. 使用定时器,每次刷新500 ms的时间就足够了,您的主应用程序将保持被动。

In all cases... 在所有情况下...

For IPC, Memory Mapped files are faster than sockets, but GDI messages are ideal when it deals with some small amount of data. 对于IPC,内存映射文件比套接字更快,但GDI消息在处理少量数据时是理想的。 Sockets are good candidates, and will be fast also on a local machine: the small overhead about Memory Mapped files won't be noticeable if the data amount transmitted is only a few KB (up to 1 MB eg); 套接字是很好的候选者,并且在本地机器上也会很快:如果传输的数据量仅为几KB(例如高达1 MB),则内存映射文件的小开销将不会显着; and if you need to create a light Client version of your application, it will still work. 如果您需要创建应用程序的轻客户端版本,它仍然可以工作。

The question to your answer depends on your requirements (assuming that you have a good reason to divide the application this way): 你的答案的问题取决于你的要求(假设你有充分的理由以这种方式划分申请):

If you need to do "trivial" tasks, ie not requring much data transfer, then it is probably better to use sockets. 如果你需要做“琐碎”的任务,即不需要太多的数据传输,那么使用套接字可能更好。 You need to create a protocol nevertheless, eg respect byte orders. 您需要创建一个协议,例如尊重字节顺序。 Please also note, that transmitting data will slow down your gui responses. 还请注意,传输数据会降低您的gui响应速度。

If you need to transfer larger amounts of data, using shared memory may be more performant. 如果需要传输大量数据,使用共享内存可能会更高效。 Please note that here you need to do the bookkeeping yourself, that is done by the tcp implementation (eg a transmit / receive buffer). 请注意,您需要自己完成簿记,这是通过tcp实现(例如发送/接收缓冲区)完成的。 Using this The problem of requiring a protocol becomes even worse. 使用此需要协议的问题变得更糟。

If you want a simple implementation then don't divide the application up into two processes. 如果您想要一个简单的实现,那么不要将应用程序分成两个进程。 Performance-wise this is not an issue, but you are adding an order of complexity above what is required in a single application. 性能方面,这不是问题,但是您要在单个应用程序中添加高于复杂性的顺序。 You would need to have an extremely good reason for dividing the application into multiple proceses to overcome the time and effort that it will cost for you to deliver the same functionality with this architecure. 您需要有一个非常充分的理由将应用程序划分为多个过程,以克服您使用此架构提供相同功能所需的时间和精力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM