JAVA RMI原理

    RMI全称Remote Method Invocation,即远程调用接口,采用CS+代理的架构。CS体现在通信两端的其中一端作为server提供服务,另一端作为client请求服务,通过socket实现网络通信。代理体现在任一端都分为两层结构,上层处理具体业务,下层实现端到端通信代理。通信架构图如下:

                        JAVA RMI原理

                                                              图-1       RMI通信架构

    在编写基于RMI架构的代码时,需要注意的两点:

        (1)RMI要求对象必须实现Remote标记接口,且所有接口都必须抛出RemoteException异常。

        (2)对象的类如果继承自UnicastRemoteObject类,必须定义显示的构造函数,并抛出

                    RemoteException异常,因为UnicastRemoteObject类的构造函数抛出了RemoteException异

                    常。

        (3)因为对象需要在网络上传输,对象的类还必须实现Serializable接口。

    构建步骤:

        (1)编写业务接口;

        (2)实现业务接口;

        (3)创建服务注册表,并绑定业务对象

        (4)客户端请求服务对象,并调用对象方法。

    示例代码如下:

    // 业务接口:

    ServerService.java:

package com.myRMI;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ServerService extends Remote {
    public String SoS(String name, String location) throws RemoteException;
}

    // 接口实现:

    ServerServiceImpl.java:

package com.myRMI;

import java.rmi.server.*;
import java.rmi.RemoteException;

public class ServerServiceImpl extends UnicastRemoteObject implements ServerService {
    private static final long serialVersionUID = 1L;

    public ServerServiceImpl() throws RemoteException {
        super();
    }
    
    public String SoS(String name, String location) throws RemoteException {
        return name + "! Police is going to " + location + " to help you out!";
    }
}

    // 服务端业务注册和绑定

    Server.java:

package com.myRMI;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class Server {
    public static void main(String[] args) throws Exception {
        ServerServiceImpl ssi = new ServerServiceImpl();
        
        // create registy & mapping service
        LocateRegistry.createRegistry(5899);
        Naming.bind("rmi://localhost:5899/ServerService", ssi);
        System.out.println("Server started!");
    }
}

    // 客户端业务查询和执行

    Client.java:

package com.myRMI;

import java.rmi.Naming;

public class Client {
    public static void main(String[] args) throws Exception {
        ServerService ss = (ServerService)Naming.lookup("rmi://localhost:5899/ServerService");
        System.out.println(ss.SoS("Jack", "North Korea"));
    }
}

    RMI通信架构基本原理就是这些,有个缺点:

        RMI使用JAVA的Serialization机制实现,其客户端和服务器端都只能是Java程序,不能跨语言;

        至于服务地址的绑定可以通过DNS来解决。

转载于:https://my.oschina.net/yepanl/blog/1585021