两个独立的 Java 桌面应用程序之间的通信

发布于 2024-08-10 08:01:02 字数 166 浏览 4 评论 0原文

我正在寻求开发两个独立的(但相关的)Java 桌面应用程序。

我希望一个应用程序能够触发另一个应用程序,传入可以编辑并传回的数据,即通信将是两种方式。如果其他应用程序已经在运行,我希望它们只是进行通信,即我不想只通过命令行传递参数等。

一般来说,我应该考虑哪些策略/技术来实现这一目标?

I'm looking to develop two separate (but related) Java desktop applications.

I want the ability for one application to trigger the other, passing in data that can then be edited and passed back, i.e. the communication will be two way. If the other application is already running I want them to just communicate, i.e. I dont want to just pass arguments over the command line, etc.

Generally speaking, what strategies/techniques should I be looking at in order to achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

一身仙ぐ女味 2024-08-17 08:01:02

为了展示让两个应用程序相互通信是多么容易,请查看这个使用 JGroups 的网络剪贴板演示。只需启动两个实例并开始将文件放入其中之一即可。第二个实例将立即显示相同的文件。

import java.io.Serializable;
import java.awt.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import org.jgroups.*;

public class JGroupsTest {

    public static void main(String[] args) throws Exception {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(500, 300);
        final DefaultListModel listModel = new DefaultListModel();
        final JList panel = new JList(listModel);
        panel.setBackground(new Color(128, 0, 40));
        panel.setForeground(new Color(240, 240, 240));
        frame.add(panel);
        System.setProperty("java.net.preferIPv4Stack", "true");
        final JChannel channel = new JChannel("udp.xml");
        channel.connect("networkclipboard");
        channel.setReceiver(new ReceiverAdapter() {
            @Override
            public void viewAccepted(View newView) {
                frame.setTitle("Network Clipboard - " + channel.getLocalAddress());
            }

            @Override
            public void receive(Message msg) {
                listModel.addElement(msg.getObject());
            }
        });

        panel.setTransferHandler(new TransferHandler() {
            @Override
            public boolean importData(JComponent comp, Transferable t) {
                DataFlavor[] transferDataFlavors = t.getTransferDataFlavors();
                for (DataFlavor flavor : transferDataFlavors) {
                    try {
                        Object data = t.getTransferData(flavor);
                        if (data instanceof Serializable) {
                            Serializable serializable = (Serializable) data;
                            Message msg = new Message();
                            msg.setObject(serializable);
                            channel.send(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return super.importData(comp, t);
            }

            @Override
            public boolean canImport(TransferSupport support) {
                return true;
            }

            @Override
            public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
                return true;
            }

        });
    }

}

To show how easy it is to let two applications communicate with each other, check out this network-clipboard demo using JGroups. Just start two instances and begin dropping files into one of them. The second instance will instantly show the same files.

import java.io.Serializable;
import java.awt.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import org.jgroups.*;

public class JGroupsTest {

    public static void main(String[] args) throws Exception {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(500, 300);
        final DefaultListModel listModel = new DefaultListModel();
        final JList panel = new JList(listModel);
        panel.setBackground(new Color(128, 0, 40));
        panel.setForeground(new Color(240, 240, 240));
        frame.add(panel);
        System.setProperty("java.net.preferIPv4Stack", "true");
        final JChannel channel = new JChannel("udp.xml");
        channel.connect("networkclipboard");
        channel.setReceiver(new ReceiverAdapter() {
            @Override
            public void viewAccepted(View newView) {
                frame.setTitle("Network Clipboard - " + channel.getLocalAddress());
            }

            @Override
            public void receive(Message msg) {
                listModel.addElement(msg.getObject());
            }
        });

        panel.setTransferHandler(new TransferHandler() {
            @Override
            public boolean importData(JComponent comp, Transferable t) {
                DataFlavor[] transferDataFlavors = t.getTransferDataFlavors();
                for (DataFlavor flavor : transferDataFlavors) {
                    try {
                        Object data = t.getTransferData(flavor);
                        if (data instanceof Serializable) {
                            Serializable serializable = (Serializable) data;
                            Message msg = new Message();
                            msg.setObject(serializable);
                            channel.send(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return super.importData(comp, t);
            }

            @Override
            public boolean canImport(TransferSupport support) {
                return true;
            }

            @Override
            public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
                return true;
            }

        });
    }

}
固执像三岁 2024-08-17 08:01:02

这取决于您希望如何通信这两个程序:

  • 如果您只需要进程间信号量,请在 /tmp 中的某个位置创建一个文件并将其锁定。

  • 如果您只需要进程间同步消息传递(远程过程调用),RMI 应该是最简单的。

  • 如果您需要异步进程间消息传递,JMS 应该是最简单的。

  • 如果需要进程间共享内存,请使用映射文件。

  • 如果您需要以上所有内容,Terracotta 是最简单的方法:不同 JVM 上的 Java 程序位于同一台机器上甚至不同的计算机看到彼此就好像它们是在一台机器上的一个 JVM 内执行一样。将一个程序拆分为几个程序甚至不需要更改任何代码 - 编写一个 XML 配置文件就足够了。

It depends how would you like to communicate those 2 programs:

  • If you need only inter-process semaphores, create a file somewhere in /tmp and lock it.

  • If you need only inter-process synchronous messaging (remote procedure call), RMI should be easiest.

  • If you need asynchronous interprocess messaging, JMS should be easiest.

  • If you need inter-process shared memory, use mapped files.

  • If you need all the above, Terracotta is the easiest way: Java programs on different JVMs on the same or even different computers see each other as if they were executed inside one JVM on one machine. Splitting one program into a few doesn't even require any code changes - it's enough to write an XML config file.

暗地喜欢 2024-08-17 08:01:02

他们每个人都可以监听 Socket本教程非常适合入门。

They could each listen on a Socket. This tutorial is good to get started.

梦行七里 2024-08-17 08:01:02

您还应该考虑优秀的经典 RMI。

You should also consider good ol' classic RMI.

夏有森光若流苏 2024-08-17 08:01:02

看看JavaGroups,它将解决你的沟通问题,也对你有帮助检测其他应用程序是否正在运行。如果应用程序没有运行,您将必须使用 java.lang.Runtime.exec() 为其启动一个新的 JVM...

Have a look at JavaGroups, it will solve your communication problem and also help you to detect if the other app is running. If the app isn't running you will have to launch a new JVM for it with java.lang.Runtime.exec()...

幸福还没到 2024-08-17 08:01:02

尝试使用 SocketCommunication 进行通信,即使应用程序位于同一台机器上。

在这里可以找到有关如何操作的更多信息(Sun /Java 文档)。

Try to communicate with SocketCommunication, even if the application are in the same machine.

Here can find more info about how to do it (Sun/Java documentation).

围归者 2024-08-17 08:01:02
  • “企业”方式是在 Java EE 服务器或至少在 Spring 框架中运行这些应用程序。这也可能太过分了。

  • 如果需要通讯一堆数据,那么 RMI 会做。

  • 如果您不害怕破坏自己的协议、数据结构和错误处理,则可以设置服务器和客户端套接字并通过它们进行通信。

  • 我认为通过公共目录中的文件(设置您自己的协议来确定谁何时写入或删除文件)或通过共享数据库进行通信的替代方案有一定的吸引力。技术含量低,速度不是特别快,但非常简单可靠。而且从外部监视“通信”相当容易。

  • The "Enterprise" way to go would be to run these apps in a Java EE server or at least in a Spring framework. It's also probably vastly overkill.

  • If a bunch of data needs to be communicated, then RMI will do it.

  • If you're not afraid to hack your own protocol, data structure and error handling, you can set up server and client sockets and communicate through those.

  • I think there's a certain crude appeal to the alternative of communicating via a file in a common directory (setting up your own protocol of who writes or erases the file when), or via a shared database. Low-tech, not extremely fast, but very simple and reliable. And it's fairly easy to monitor "communication" from the outside.

尛丟丟 2024-08-17 08:01:02

为了简单起见,为什么不直接使用普通的 TCP 套接字呢?

To keep things simple why not just use plain TCP sockets?

删除会话 2024-08-17 08:01:02

我第二个Socket通信和RMI。 RMI 稍微复杂一些,但对于程序员来说更直观。这取决于您发送的信息类型。将原始字节推送到另一台机器可能比运行 RMI 服务器并处理所有这些爵士乐更有意义......

I second Socket communication and RMI. RMI is a little more involved but is more intuitive to a programmer. It depends on what type of information you are sending though. Pushing raw bytes over to another machine might make more sense then running the RMI server and dealing with all that jazz...

笑脸一如从前 2024-08-17 08:01:02

这取决于您想在两个应用程序之间进行哪种通信。例如,如果您使用套接字或 RMI,则两个应用程序都需要启动才能进行通信。如果您想要进行的通信类型可以更加异步,那么您可以更多地使用基于消息传递的方法。

例如,ZooKeeper 允许您在非常简单但功能强大的原语之上实现几乎任何您想要的东西。此页面(http://hadoop.apache.org/zookeeper/docs/current /recipes.html)解释了如何使用 ZooKeeper 构建更高级别的构造。

缺点是您需要另一个系统。例如,如果您使用 JGroups,那么您就不需要。

希望这有帮助

It depends what kind of communication you want to do between the 2 apps. If you use sockets or RMI for example, both applications need to be up in order for the communication to happen. If the kind of communication you want to do can be more asynchronous then you can use more of a messaging based approach.

For example, ZooKeeper allows you to implement pretty much anything you want on top of very simple yet powerful primitives. This page (http://hadoop.apache.org/zookeeper/docs/current/recipes.html) explains how to build higher level constructs with ZooKeeper.

The drawback is that you need another system. If you use JGroups for example then you don't.

Hope this helps

旧人哭 2024-08-17 08:01:02

根据您正在寻找的通信方式(高延迟、大量数据等)以及该系统是否可以扩展到超过 2 个 java 系统,可能是使用 Tibco 等中间件解决方案的消息传递系统智能插座。

有关您的设置和期望的更多信息都会有所帮助。

Depending on what style of communication you're looking for (high latency, lots of data, etc.) and whether or not this system may expand past simply 2 java systems, a possibility could be a messaging system using a middleware solution such as Tibco SmartSockets.

Any more info on your setup and expectations would help.

み零 2024-08-17 08:01:02

最简单的方法是在没有独立 rmiregistry 的情况下使用 RMI。

服务器创建一个本地注册表:

ServerImpl extends UnicastRemoteObject implements Server

rmiRegistry = LocateRegistry.createRegistry(2020);
rmiRegistry.bind("server", aServerImpl);

客户端使用 rmi url 查找它(类似于 corbaloc:)

String url = "rmi://localhost:2020/server";
Server server = (Server) Naming.lookup(url);

我在 500 毫秒内循环调用了 1000 个调用相同的开放连接。是的,那就是毫秒。

想法和示例来自此处: https:// www.censhare.com/us/resources/blog/article/file-streaming-using-java-rmi

The easiest is to use RMI without standalone rmiregistry.

Server creates a local registry:

ServerImpl extends UnicastRemoteObject implements Server

rmiRegistry = LocateRegistry.createRegistry(2020);
rmiRegistry.bind("server", aServerImpl);

Client looks it up with an rmi url (similar to corbaloc:)

String url = "rmi://localhost:2020/server";
Server server = (Server) Naming.lookup(url);

I got 1000 calls in under 500 ms in a loop over the same open connection. Yes, that is milliseconds.

Idea and sample from here: https://www.censhare.com/us/resources/blog/article/file-streaming-using-java-rmi

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文