如何使用Java RMI从服务器向客户端发送消息? [英] How to send a message from Server to Client using Java RMI?

查看:459
本文介绍了如何使用Java RMI从服务器向客户端发送消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该应用程序是局域网的项目管理应用程序,它有项目,任务等对象。所以RMI似乎是要走的路。

The application is a Project Management application for a LAN, and it has objects such as Project, Task, etc. So RMI seemed like the way to go.

但是,当其他客户端触发事件时,它还会向某些客户端发送实时通知。我读到服务器无法跟踪已在RMI中连接到它的客户端。因此,作为一个选项,我认为服务器可以像预先连接到服务器的客户端一样连接到客户端。这是怎么做的?

But it also has live notifications sent to certain clients as events are triggered by other clients. I read that Servers cannot keep track of the clients that has been connected to it in RMI. So as an option I think the server could connect to the client like the client connected to the server beforehand. Is this how it is done?

如果没有,我应该在这种情况下采用套接字编程吗?

If not, should I resort to socket programming in this situation?

如果这是一个愚蠢的问题,请提前道歉。

Apologies in advance if this is a stupid question.

推荐答案

你的假设正确。

对于从服务器到客户端的主动推送式通知,客户端也必须是服务器。

For active push-style notification from server to clients, the clients have to be "servers" also.

所以在客户端应用程序中你也是需要有一个远程接口。客户端第一次连接到服务器时,会向其传递对远程接口实例的引用。

So in the client app you also need to have a remote interface. The first time the client connects to the server you pass to it a reference to an instance of the remote interface.

此对象需要导出为远程RMI对象,但它不需要在注册表中注册,因为您将直接将引用传递给需要在其上调用方法的服务器。

This object needs to be exported as a remote RMI object, but it doesn't need to be registered in a registry, since you will directly pass a reference to it to the server who needs to call methods on it.

服务器保留所有客户的注册表,以便在需要时回拨。通常是一个Map,其中key是客户端的有意义标识符,值是客户端的远程引用。

The server keeps a register of all the clients so it can call back when needed. Typically a Map with the key being a meaningful identifier of the clients and the value being the remote reference to the client.

当客户端应用程序关闭时,客户端需要取消注册。

When the client app is shut down, the client needs to unregister.

并且服务器可能希望定期检查所有客户端,以便它不会保留对死客户端的引用。

And the the server will probably want to have a periodic check of all the clients so it doesn't keep references to dead clients.

你的服务器界面看起来像这样:

Your server interface would look something like that :

public interface Server extends Remote {

    void register(Client client) throws RemoteException;

    void unregister(Client client) throws RemoteException;

    void doSomethingUseful(...) throws RemoteException;

    ...

}

您的客户端界面:

public interface ClientCallbackInterface extends Remote {

    void ping() throws RemoteException;

    void notifyChanges(...) throws RemoteException;

}

在您的客户端应用启动代码的某处:

And somewhere in your client app startup code :

ClientCallbackInterface client = new ClientImpl();

UnicastRemoteObject.exportObject(client);

Registry registry = LocateRegistry.getRegistry(serverIp, serverRegistryPort); 

Server server = (Server) registry.lookup(serviceName);

server.register(client);

完全可以实现它。但不是微不足道的。你必须要处理很多事情:

It is totally possible to implement it. But not trivial. There are many things you have to take care of :


  • 如果涉及防火墙,你必须注意哪个可能有问题。

  • 也可能是本地操作系统防火墙出现问题,您的客户端应用程序实际上必须打开本地传入端口

  • 如果您尝试在同一台计算机上启动多个客户端你会有港口冲突,也必须照顾好这个

  • 完全没有在LAN外工作

  • You must take care of which can be a problem if there are firewalls involved.
  • Could be problems with local OS firewall too, your client app actually must open local incoming ports
  • If you try to start several clients on the same machine you will have port conflict, must take care of that too
  • Totally not going to work outside of LAN

我确实实现了这样的系统并且工作正常。但是如果我不得不再做一次,我肯定会使用别的东西,可能是 REST 服务和 WebSockets 回调。它对网络部分的限制要少得多,只需要HTTP。

I did implement a system like this and it works fine. But all that said if I had to do it again I would definitely use something else, probably REST services and WebSockets for the callbacks. It would be much less constraints on the network part, just HTTP needed.

这篇关于如何使用Java RMI从服务器向客户端发送消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆