【RPC】RMI远程调用(二)

RPC和RMI的区别

RPC RMI
客户端通过网络请求调用某种服务 在客户端Java虚拟机上的对象像调用本地对象一样调用服务端java 虚拟机中的对象上的方法

Demo结构

 接口API

//RMI要用Remote接口实现
public interface FirstInterface extends Remote {
    //所有Remote都需要抛出exception
    String first(String name) throws RemoteException;
}

服务端

1、实现远程服务接口

/**
 * 需要实现远程服务接口 直接实现 or 间接实现
 */
public class FirstRMIImpl extends UnicastRemoteObject implements FirstInterface, Remote {
    //构造方法需要抛出remoteException异常
    public FirstRMIImpl() throws RemoteException{
        super();
    }
    //不会创建RMI服务,可以继承UnicastRemoteObject类型
    //所有方法都要抛出异常,包括构造方法
    @Override
    public String first(String name) throws RemoteException {
        System.out.println("客户端请求参数是:"+name);
        return "你好,"+name;
    }
}

UnicastRemoteObject 可以将当前对象暴露出来,让其他客户端调用

2、提供服务,注册到注册中心上

public class Main {
    //RMI在注册中心创建时,会自动创建一个子线程,升级为守护线程,长期运行,不会挂掉
    public static void main(String[] args) {
        try {
            System.out.println("服务器启动中!");
            FirstRMIImpl firstRMI = new FirstRMIImpl();
            System.out.println(LocateRegistry.getRegistry(9999));
            //注册到 注册中心上 正整数<655536
            LocateRegistry.createRegistry(9999);
            System.out.println(LocateRegistry.getRegistry(9999));
            //绑定服务到注册中心,格式:rmi://ip:port/别名
            //命名重复会抛异常:已绑定异常
//            Naming.bind("rmi://localhost:9999/first",firstRMI);
            //重新绑定一个服务到注册中心,命名冲突:直接覆盖,不会抛出异常
            Naming.rebind("rmi://localhost:9999/first",firstRMI);
            System.out.println("服务器启动完毕!");
            //进程关闭
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

绑定服务到注册中心,有两种方法:

1、Naming.bind() 如果命名冲突,会抛出异常

2、Naming.rebind() 如果命名冲突,也不会抛出异常,会直接覆盖

服务注册到注册中心的格式:rmi://ip:port/别名

客户端

1、在注册中心寻找服务 并 调用

public class ClientMainClass {
    public static void main(String[] args) {
        //创建代理对象
        FirstInterface first=null;
        try {
            //通过名字找服务,并自动创建代理对象
            //类型时Object,对象一定是Proxy的子类型,且实现了服务接口
            first= (FirstInterface) Naming.lookup("rmi://localhost:9999/first");
            String str = first.first("janejanejane");
            System.out.println("对象类型:"+first.getClass().getName());
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Naming.lookup()寻找服务

猜你喜欢

转载自blog.csdn.net/kanseu/article/details/123801237