【问题标题】:Java RMI: how can two clients communicate with their referencesJava RMI:两个客户端如何与其引用进行通信
【发布时间】:2017-06-15 21:45:44
【问题描述】:

我的作业是学习 RMI。我需要创建一个服务器和多个客户端实例。

每个客户端都连接到服务器,服务器必须保存所有客户端的列表。然后服务器将所有客户端的网络连接列表返回给每个客户端,以便它们可以调用彼此的方法而无需使用服务器。

我得到了每个客户端连接到服务器工作的部分。但我不明白要保留什么以及向客户发送什么以便他们可以相互交流。

我目前正在尝试在使用服务器的“registerToBank”方法时保留远程引用列表。我离解决方案还远吗?

谢谢

这是当前代码:

服务器界面

package banqueRmiInterface;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.HashMap;

import utils.SuccursaleInformationsContainer;

public interface BanqueRMIInterface extends Remote {
    public int registerToBank(int moneyAmount) throws RemoteException;
}

服务器:

package banque;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.RemoteRef;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

import banqueRmiInterface.BanqueRMIInterface;
import succursale.Succursale;
import utils.SuccursaleInformationsContainer;

public class Banque extends UnicastRemoteObject implements BanqueRMIInterface{
private static final long serialVersionUID = 1L;
int totalMoney = 0;
List<Succursale> remoteObjectList = new ArrayList<Succursale>();

protected Banque() throws RemoteException {
    super();

}

@Override
public int registerToBank(int moneyAmount, Succursale succursale) throws RemoteException{
    succursale.setId(remoteObjectList.size());
    remoteObjectList.add(succursale);
    totalMoney += moneyAmount;
    System.out.println(" succurcale #" + succursale.getId() + " added "  + moneyAmount + "$ to the lot");
    System.out.println("New total of money is: " + totalMoney);

    updateClientsRemoteObjectList();

    return remoteObjectList.size()-1;
}

public static void main(String[] args){
    try {
        startRmiRegistry();

        Naming.rebind("//127.0.0.1/Bank", new Banque()); //Change this for your own ip

        System.out.println("Server ready");

    } catch (Exception e) {
        System.err.println("Server exception: " + e.toString());
      e.printStackTrace();
    }
}

public void updateClientsRemoteObjectList(){
    for(int i = 0; i < remoteObjectList.size(); i++){
        System.out.println("updating client #" +remoteObjectList.get(i).getId() );
        remoteObjectList.get(i).updateRemoteObjectList(remoteObjectList);
    }
}


public static void startRmiRegistry(){
    try {
        java.rmi.registry.LocateRegistry.createRegistry(1099);
        System.out.println("RMI registry ready.");
    } catch (Exception e) {
        System.out.println("Exception starting RMI registry:");
        e.printStackTrace();
    }
}

}

客户:

public class Succursale implements Serializable{
/**
 * 
 */
private static final long serialVersionUID = -905645444505287895L;
private BanqueRMIInterface look_up;
private int id = 0;
private List<Succursale> remoteObjectList;

public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException, Exception{
    Succursale test = new Succursale();
    test.doThings();

}

public void doThings() throws RemoteException, MalformedURLException, NotBoundException, Exception{
    look_up = (BanqueRMIInterface) Naming.lookup("//127.0.0.1/Bank"); //Change this for your own ip
    System.out.println("Combien d'argent vous avez?");
    BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
    String userInput;
    int moneyAmount =0;
    if ((userInput = stdIn.readLine()) != null) 
    {
        System.out.println(userInput);
        moneyAmount = Integer.parseInt(userInput);

    }


    id = look_up.registerToBank(moneyAmount, this);

    while(true)
    {
        //do things
    }
}

public void updateRemoteObjectList(List<Succursale> remoteObjectList){
    this.remoteObjectList = remoteObjectList;
}

public int getId(){
    return this.id;
}
public void setId(int id){
    this.id = id;
}

}

【问题讨论】:

  • 每个客户端如何相互通信?如果他们通过 RMI 进行通信,那么您必须向每个客户端公开 RMI 接口。
  • “返回网络连接列表”是什么意思?您不能将网络连接返回到远程服务器,以便在不同的服务器(不同的位置)中使用!
  • @Zico 你能发表你的评论作为答案吗?这是对我有用的解决方案,谢谢!
  • @Zicco 你能告诉我们这到底意味着什么吗?

标签: java rmi


【解决方案1】:

每个客户如何相互交流? 如果他们通过 RMI 进行通信,那么您必须向每个客户端公开 RMI 接口。并且您不能将网络连接返回到远程服务器,以便在不同的服务器(不同的位置)中使用!

【讨论】:

  • 最后一句话很难理解,但根本不正确。 RMI 存根本质上“连接到远程服务器”,或者至少是这样做的手段,并且不会神奇地改变它的目标位置:并且它的其余部分不会从第一部分。
  • 最后一句实际上是对这部分问题的陈述“服务器然后将所有客户端的网络连接列表返回给每个客户端,以便他们可以在不必使用服务器的情况下调用彼此的方法。”我不确定这怎么可能根本不正确?
【解决方案2】:

答案就在你的标题中。 '与他们的参考'。客户端所要做的就是从服务器获取对另一个客户端的远程引用,然后以正常方式开始使用它。

防火墙允许。

【讨论】:

  • 您好,感谢您的回答。你能详细说明一下吗?我现在很迷茫。我尝试更改客户端,使其创建自己的对象,然后将“this”传递给服务器。但是当服务器试图从他保留的客户端对象中调用方法时。更改不会出现在客户端上,而是出现在他保留的客户端对象上......将更新问题中的代码
  • 或者我完全错了,您必须将每个客户端注册到 rmi 注册表,以便他们可以互相调用?
  • 客户端必须将自己导出为实现远程接口的远程对象,与服务器一样。目前,您的客户端只是可序列化的,它将其实体传输到服务器。您无需对 RMI 注册表进行任何操作。
猜你喜欢
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多