RPC(6): RMI implementiert RPC

1RMI-Einführung

RMI (Remote Method Invocation) Remote-Methodenaufruf.

RMI ist eine von JDK1.2 gestartete Funktion, die es einer Java-Anwendung ermöglicht, Inhalte in einer Java-Anwendung (JVM) auf einem anderen Server aufzurufen, genau wie das Aufrufen lokaler Methoden.

RMI ist ein Remote-Aufruf in der Java-Sprache und kann nicht sprachübergreifend implementiert werden.

2 Ausführungsprozess

Die Registrierung ist der Namespace, in dem alle Serverobjekte platziert werden. Jedes Mal, wenn der Server ein Objekt erstellt, registriert er das Objekt mithilfe der Methode bind() oder rebind(). Diese werden unter Verwendung eines eindeutigen Namens registriert, der als Bindungsname bezeichnet wird.

Um ein Remote-Objekt aufzurufen, benötigt der Client eine Referenz auf das Objekt. Das heißt, das Objekt wird aus der Registrierung über den an den Server gebundenen Namen abgerufen (Methode „lookup()“).

3 API-Einführung

3.1 Fernbedienung

java.rmi.Remote definiert diese Schnittstelle als Remote-Aufrufschnittstelle. Wenn die Schnittstelle extern aufgerufen wird, muss diese Schnittstelle geerbt werden.

3.2 RemoteException

java.rmi.RemoteException

In einer Schnittstelle, die die Remote-Schnittstelle erbt, muss diese Ausnahme ausgelöst werden, wenn die Methode remote aufgerufen werden darf.

3.3 UnicastRemoteObject

java.rmi.server.UnicastRemoteObject

Diese Klasse implementiert die Remote-Schnittstelle und die Serializable-Schnittstelle.

Zusätzlich zur Implementierung der benutzerdefinierten Schnittstelle muss die Implementierungsklasse der benutzerdefinierten Schnittstelle diese Klasse auch erben.

3.4 LocateRegistry

java.rmi.registry.LocateRegistry

Sie können über LocateRegistry eine Registrierung auf dem lokalen Computer erstellen und über einen bestimmten Port auf diese Registrierung zugreifen.

3.5 Wir

java.rmi.Naming

Die Benennung definiert den RMI-Namen, unter dem auf veröffentlichte Inhalte zugegriffen werden kann. Die angegebene Remote-Methode wird auch durch Benennung erhalten.

4 Code-Implementierung

4.1 RMI-Schnittstelle erstellen

Schnittstellendatei schreiben

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 Server erstellen

POM-Datei einführen

<?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>

Schreiben Sie eine Remote-Service-Schnittstelle

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;
    }
}

Erstellen Sie eine Startup-Klasse und registrieren Sie den Dienst in der Registrierung

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();
        }
    }
}

Starten Sie den Dienst und die Ergebnisse sind wie folgt:

4.3 Client erstellen

Führen Sie Pom-Abhängigkeiten ein

<?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>

Schreiben Sie einen Dienst, der den RPC-Dienst von RMI aufruft

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();
        }
    }
}

Starten Sie den Dienst und die Ergebnisse sind wie folgt:

Wenn Sie zu diesem Zeitpunkt das Serverprogramm überprüfen, werden die von der Verbindung angeforderten Dienste angezeigt. Der Effekt ist wie folgt:

Je suppose que tu aimes

Origine blog.csdn.net/u013938578/article/details/135205286
RPC
conseillé
Classement