RPC(6): RMI implements RPC

1RMI Introduction

RMI (Remote Method Invocation) remote method invocation.

RMI is a function launched from JDK1.2, which allows a Java application to call content in a Java application (JVM) in another server just like calling local methods.

RMI is a remote call in Java language and cannot be implemented across languages.

2 Execution process

Registry is the namespace where all server objects are placed. Every time the server creates an object, it registers the object using the bind() or rebind() method. These are registered using a unique name called a binding name.

To call a remote object, the client needs a reference to the object. That is, the object is obtained from the registry through the name bound to the server (lookup() method).

3 API introduction

3.1 Remote

java.rmi.Remote defines this interface as a remote calling interface. If the interface is called externally, this interface needs to be inherited.

3.2 RemoteException

java.rmi.RemoteException

In an interface that inherits the Remote interface, if the method is allowed to be called remotely, this exception needs to be thrown.

3.3 UnicastRemoteObject

java.rmi.server.UnicastRemoteObject

This class implements the Remote interface and Serializable interface.

In addition to implementing the custom interface, the custom interface implementation class also needs to inherit this class.

3.4 LocateRegistry

java.rmi.registry.LocateRegistry

You can create a Registry on the local machine through LocateRegistry, and you can access this Registry through a specific port.

3.5 We

java.rmi.Naming

Naming defines the RMI name by which published content can be accessed. The specified remote method is also obtained through Naming.

4 code implementation

4.1 Create RMI interface

Write interface file

package com.example.demo;

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

// 定义一个远程服务接口。RMI强制要求,必须是Remote接口的实现。
public interface FirstInterface extends Remote {
    // RMI强制要求,所有的远程服务方法,必须抛出RemoteException。
    String first(String name) throws RemoteException;
}

4.2 Create server

Introduce pom file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi_rpc</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi_rpc_server</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi_rpc_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

Write remote service interface

package com.example.demo.impl;

import com.example.demo.FirstInterface;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

// 实现远程服务接口。 所有的远程服务实现,必须是Remote接口直接或间接实现类。
// 如果不会创建基于RMI的服务标准实现,可以继承UnicastRemoteObject类型。
// RMI强制要求,所有的方法必须抛出RemoteException,包括构造方法。
public class FirstRMIImpl extends UnicastRemoteObject implements FirstInterface, Remote {
    public FirstRMIImpl() throws RemoteException {
        super();
    }

    public String first(String name) throws RemoteException {
        System.out.println("客户端请求参数是:" + name);
        return "你好," + name;
    }
}

Create a startup class and register the service on the Registry

package com.example.demo;

import com.example.demo.impl.FirstRMIImpl;

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

// 主方法,创建一个服务实现对象,提供服务,并注册到Registry上。
// RMI的Registry在创建的时候,会自动启动一个子线程,并升级为守护线程(服务线程|精灵线程)。提供持久的服务。
public class MainClass {
    public static void main(String[] args) {
        try {
            System.out.println("服务器启动中...");
            // 创建服务对象
            FirstInterface first = new FirstRMIImpl();
            // 注册到Registry(注册中心)上。
            LocateRegistry.createRegistry(9999);
            // 绑定一个服务到注册中心。提供命名,格式为:rmi://ip:port/别名
            // 如果服务重复,抛出异常。 重复的定义是命名冲突。
            // Naming.bind("rmi://localhost:9999/first", first);
            // 重新绑定一个服务到自注册中心。 和bind的区别是,命名冲突,直接覆盖。
            Naming.rebind("rmi://localhost:9999/first", first);

            System.out.println("服务器启动完毕!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

Start the service and the results are as follows:

4.3 Create client

Introduce pom dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi_rpc</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi_rpc_client</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi_rpc_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

Write a service that calls RMI's RPC service

package com.example.demo;

import java.rmi.Naming;

// 客户端主方法
public class ClientMainClass {
    public static void main(String[] args) {
        // 代理对象的创建。
        FirstInterface first = null;
        try{
            // 使用lookup找服务。通过名字找服务,并自动创建代理对象。
            // 类型是Object,对象一定是Proxy的子类型,且一定实现了服务接口。
            first = (FirstInterface) Naming.lookup("rmi://localhost:9999/first");

            System.out.println("对象的类型是:" + first.getClass().getName());
            String result = first.first("S106,今天课程讲不完了");
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

Start the service and the results are as follows:

At this time, if you check the server program, the services requested by the connection will be displayed. The effect is as follows:

Guess you like

Origin blog.csdn.net/u013938578/article/details/135205286
RPC
RPC