Java RMI : how to make client stub method called on server print message on client screen?

标签 java rmi

我正在用 Java 与 rmi 聊天。我有一个服务器对象和至少两个客户端对象。当客户端远程调用recebeMensagem方法向服务器发送消息时,服务器必须在所有客户端的屏幕上打印该消息(发送消息的客户端除外)。

客户端类有一个方法printMenssagem(Mensagem msg),该方法由服务器远程调用。问题是该方法正在服务器的屏幕上打印。如何在客户端屏幕上打印消息?

服务器.java:

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.function.Predicate;

public class Server implements ChatServer {

    private ArrayList<String> listaClientes = new ArrayList<>();
    private static int port = 5002;

    public static void main(String[] args) {

        try {

            Server obj = new Server();
            ChatServer stub = (ChatServer) 
            UnicastRemoteObject.exportObject(obj, port);

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.createRegistry(port);
            registry.bind("chat", stub);
            System.out.println("Server ready!");

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

   @Override
   public void adicionaCliente(String user) {

       this.listaClientes.add(user);

   }

   @Override
   public void retiraCliente(String userName) {
        Predicate<String> clientePredicate = cp -> 
        cp.equals(userName);
        listaClientes.removeIf(clientePredicate);
        try {
           Registry registry = LocateRegistry.getRegistry(port);
           registry.unbind(userName);
       } catch (RemoteException e) {
           e.printStackTrace();
       } catch (NotBoundException e) {
           e.printStackTrace();
       }

   }

   @Override
   public void recebeMensagem(Mensagem msg) {       

      try {
           Registry registry = LocateRegistry.getRegistry(port);
           for(String cliente : listaClientes) {
               if (!cliente.equals(msg.getRemetente())) {
                   Client stub = (Client) registry.lookup(cliente);
                   stub.printMensagem(msg);
               }                    
           }
       } catch (RemoteException e) {
        e.printStackTrace();
    } catch (NotBoundException e) {
        e.printStackTrace();
    }

    }


    public ArrayList<String> getListaClientes() {
        return listaClientes;
   }

   public void setListaClientes(ArrayList<String> listaClientes) {
       this.listaClientes = listaClientes;
   } 



  }

Client.java:

import java.io.Serializable;
import java.rmi.Remote;

public class Client implements Remote, Serializable {

    private static final long serialVersionUID = 6864579049922061838L;
    private static int port = 5002;
    private static String host = "127.0.0.1";

    public static void main(String[] args) {        

        new Thread(new ClientInterface(host, port)).start();            
    }


    public void printMensagem(Mensagem mensagem) {
        System.out.println(mensagem.getRemetente() + ": " + mensagem.getMensagem());
    }



}

最佳答案

how to make client stub method called on server print message on client screen?

客户端没有 stub 。它不是一个远程对象。它是一个可序列化的对象,并且已被传输到注册表 holus bolus,并且它在执行 Registry.lookup() 来获取它的任何 JVM 中运行。这不是你想要的。您希望它是一个带有 stub 的远程对象,因此您必须使其实现远程接口(interface),并将其导出,并通过对等方的远程接口(interface)使用它。

您还需要注意,您当前的架构无法在多个主机上工作,因为您无法绑定(bind)到远程注册表。您需要向服务器添加客户端注册方法。

关于Java RMI : how to make client stub method called on server print message on client screen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46374930/

相关文章:

java - 客户端是否必须知道 RMI 服务器返回的对象的 Impl?

java - cxf Web 服务不更新

java - 如何从互联网快捷方式获取目标路径?

java - 设置 rmiregistry 的堆大小

java RMI与非java实体通信?

java - rmic 编译中未找到类错误

java - 线程 "main"java.lang.NoSuchMethodError : <method> 中的 JNI GetMethodID 异常

Java:StringBuilder 的线程安全

java - 如何通过在文本字段中输入编号来创建数组,Java 小程序

java - 单播与可移植远程对象