look again, the power is unlimited. Hello world search "1611699f3abf4f 1611699f3abf50 program monkey Alang ".
This article Github.com/niumoo/JavaNotes and unread code blog has been included, there are many knowledge points and series of articles.

Introduction to RMI

RMI (Remote Method Invocation) The model is a distributed object application. Using RMI technology can make an object in a JVM call an object method in another JVM and obtain the call result. The other JVM here can be on the same computer or a remote computer. Therefore, RMI means that a Server terminal and a Client terminal are required.

The server side usually creates an object and makes it accessible remotely.

  • This object is called a remote object.
  • The server needs to register this object to be remotely accessed by the client.

The client side calls methods on objects that can be accessed remotely, and the client side can communicate with the server side and transfer information to each other.

Having said that, did you find that using RMI is very convenient when building a distributed application? It RPC , and it is even very similar to the current microservice thinking.

How RMI works

As the saying goes, "knowing what is happening, knowing what is happening", before starting to write RMI code, it is necessary to understand the working principle of RMI. How does the client side communicate with the server side in RMI?

The figure below can help us understand the workflow of RMI.

RMI Connection

As you can see from the figure, there is Stub on the Client side, which is sometimes called a stub. It is the proxy object of the RMI Client. Stub is to construct an information block when requesting a remote method. The RMI protocol will send this information block to the Server side.

This information block consists of several parts:

  • The remote object identifier.
  • Description of the method called.
  • The parameter value after marshalling (object serialization is used in the RMI protocol).

Since there is a stub on the client side that can construct an information block and send it to the server side, there must be an object on the server side that receives this information quickly, called Skeleton .

Its main work is:

  • Analyze the calling object identifier and method description in the information block, and call the specific object method on the Server side.
  • Get the return value or abnormal value of the call.
  • Group the return value and return it to the client Stub.

At this point, the result of a call from the Client to the Server can be obtained.

RMI development

Through the above introduction, I know the concept of RMI and the working principle of RMI, the following describes the development process of RMI.

Here will be demonstrated through a scenario, assuming that the client side needs to query user information, and the user information exists on the server side, so the RMI protocol interface is opened on the server side for the client to call and query.

RMI Server

The server side is mainly to construct a class User that can be transmitted, and a class UserService that can be accessed remotely. At the same time, this object must be registered with RMI and open to clients.

  1. Define the server interface (need to inherit the Remote class, the method needs to throw RemoteException ).

    package com.wdbyte.rmi.server;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    
    /**
     * RMI Server
     *
     * @author www.wdbyte.com
     * @date 2021/05/08
     */
    public interface UserService extends Remote {
    
        /**
         * 查找用户
         * 
         * @param userId
         * @return
         * @throws RemoteException
         */
        User findUser(String userId) throws RemoteException;
    }

The User object is defined in step 3.

  1. Implement server interface (need to inherit UnicastRemoteObject class to implement the defined interface).

    package com.wdbyte.rmi.server;
    
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    /**
     * @author www.wdbyte.com
     * @date 2021/05/08
     */
    public class UserServiceImpl extends UnicastRemoteObject implements UserService {
    
        protected UserServiceImpl() throws RemoteException {
        }
    
        @Override
        public User findUser(String userId) throws RemoteException {
            // 加载在查询
             if ("00001".equals(userId)) {
                User user = new User();
                user.setName("金庸");
                user.setAge(100);
                user.setSkill("写作");
                return user;
            }
            throw new RemoteException("查无此人");
        }
    }
  2. Define the transmitted object, and the transmitted object needs to implement the serialization ( Serializable ) interface.

    The class that needs to be transmitted must implement the serialization interface, otherwise an error will be reported during transmission. How to generate serialVersionUID in IDEA, a simple tutorial is also attached at the end of the article.

    package com.wdbyte.rmi.server;
    
    import java.io.Serializable;
    
    /**
     *
     * @author www.wdbyte.com
     * @date 2021/05/08
     */
    public class User implements Serializable {
    
        private static final long serialVersionUID = 6490921832856589236L;
    
        private String name;
        private Integer age;
        private String skill;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getSkill() {
            return skill;
        }
    
        public void setSkill(String skill) {
            this.skill = skill;
        }
        
        @Override
        public String toString() {
            return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", skill='" + skill + '\'' +
                '}';
        }
    }
  3. Register (rmiregistry) the remote object and start the server program.

    The server is bound to the UserService object as the remote access object, and the port is set to 1900 at startup.

    package com.wdbyte.rmi.server;
    
    import java.rmi.Naming;
    import java.rmi.registry.LocateRegistry;
    
    /**
     * RMI Server 端
     *
     * @author https://www.wdbyte.com
     * @date 2021/05/08
     */
    public class RmiServer {
    
        public static void main(String[] args) {
            try {
                UserService userService = new UserServiceImpl();
                LocateRegistry.createRegistry(1900);
                Naming.rebind("rmi://localhost:1900/user", userService);
                System.out.println("start server,port is 1900");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

RMI Client

Compared to the server side, the client side is much simpler. Directly introduce the classes that can be accessed remotely and need to be transmitted, and you can initiate a call through the port and the address bound to the Server side.

package com.wdbyte.rmi.client;

import java.rmi.Naming;

import com.wdbyte.rmi.server.User;
import com.wdbyte.rmi.server.UserService;

/**
 * @author https://www.wdbyte.com
 * @date 2021/05/08
 */
public class RmiClient {
    public static void main(String args[]) {
        User answer;
        String userId = "00001";
        try {
            // lookup method to find reference of remote object
            UserService access = (UserService)Naming.lookup("rmi://localhost:1900/user");
            answer = access.findUser(userId);
            System.out.println("query:" + userId);
            System.out.println("result:" + answer);
        } catch (Exception ae) {
            System.out.println(ae);
        }
    }
}

RMI test

Start the Server side.

start server,port is 1900

Start the Client side.

query:00001
result:User{name='金庸', age=100, skill='写作'}

If the client side passes in a userId that does not exist.

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.RemoteException: 查无此人

Generation of serialVersionUID

Generate serialVersionUID in IDEA, open the settings, and check it as shown in the figure below.

IDEA 设置

Select the class that you want to generate serialVersionUID, and press the smart prompt shortcut key.

IDEA serialVersionUID

refer to

[1] https://docs.oracle.com/javase/tutorial/rmi/overview.html

subscription

Hello world:) I am Aran, a first-line technical tool person, and write articles seriously.

1611699f3ac5b8 likes likes 1611699f3ac5b9 is a talent, not only looks handsome, but also speaks nicely.

The article is continuously updated. You can follow the public Program " or visit " Unread Code Blog ".

Reply [Information] There are various series of knowledge points and must-read books I prepared.

This article Github.com/niumoo/JavaNotes has been included, there are many knowledge points and series of articles, welcome to Star.

等你好久


程序猿阿朗
376 声望1.8k 粉丝

Hello world :)