zoukankan      html  css  js  c++  java
  • RMI


    1、制作远程接口:
    (1)扩展java.rmi.Remote接口,Remote和Serializable一样,没有具体的方法需要实现
    (2)声明所有的方法都会抛出RemoteException
      使用远程接口调用服务。调用 实现远程接口的Stub上的方法,而Stub底层用到了网络和I/O,所以各种坏事都可能会发生。这种风险,通过处理或声明远程异常来解决。如果接口中的方法声明了异常,任何在接口类型的引用上调用方法的代码也必须处理或声明异常。
    (3)确定变量和返回值是属于原语(primitive)类型或者可序列化(Serializable)类型
      远程方法的变量和返回值,必须属于原语类型或Serializable类型。因为远程方法的变量必须被打包并通过网络运送,这要靠序列化来完成。
      如果使用原语类型、字符串和许多API中内定的类型(包括数组和集合),都不会有问题。如果传送自己定义的类,就必须保证类实现了Serializable

    package rmi;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    /*2015-8-25*/
    public interface MyRemote extends Remote {
        String sayHello() throws RemoteException;
    }

    2、制作远程实现
    (1)实现远程接口
      服务必须实现远程接口,也就是客户将要调用的方法和接口
    (2)扩展UnicastRemoteObject
      为了要成为远程服务对象,对象需要实现某些“远程的”功能。最简单的方式是扩展java.rmi.server.UnicastRemoteObject,让超类帮做这些工作
    (3)设计一个不带变量的构造器,并声明RemoteException
      超类UnicastRemoteObject带来一个小问题:它的构造函数抛出RemoteException。当类被实例化的时候,超类的构造器总是会被调用。如果超类的构造器抛出异常,子类也需要有一个相同结构的构造函数
    (4)用RMI Registry注册此服务
      将此服务实例化,然后放进RMI registry中(提供服务时,RMI Registry窗口需要一直运行)
      当注册这个实现对象时,RMI系统其它注册的是stub,因为这是Client真正需要的。注册服务使用了java.rmi.Naming类的静态rebind()方法。

    package rmi;
    
    import java.net.MalformedURLException;
    import java.rmi.Naming;
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    /*2015-8-25*/
    public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
    
        private static final long serialVersionUID = 5403377671501315102L;
    
        protected MyRemoteImpl() throws RemoteException {
            super();
        }
    
    
        @Override
        public String sayHello() throws RemoteException {
            return "Server says,' Hello RMI!'";
        }
    
    }

    3、产生Stub和Skeleton
    在远程实现类(是编译后生成的class文件)上执行rmic
    rmic是JDK内的一个工具,用来为一个服务类产生stub和skeleton。命名习惯是在远程实现的名字后面加上_Stub和_Skel

    4、执行rmiregistry
      开启一个终端,启动rmiregistry
      cd到classes目录,执行rmiregistry

    5、启动服务
     开启另一个终端,启动服务
     从哪里启动?可能是从你的远程实现类的main()方法,也可能是从一个独立的启动类。
     譬如:从实现类中的main()方法启动的,先实例化一个服务对象,然后到RMI registry中注册

    package rmi;
    
    import java.net.MalformedURLException;
    import java.rmi.Naming;
    import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    
    /*2015-8-25*/
    public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
    
        private static final long serialVersionUID = 5403377671501315102L;
    
        protected MyRemoteImpl() throws RemoteException {
            super();
        }
    
        /**
         * @param args
         * @throws RemoteException
         * @throws MalformedURLException
         */
        public static void main(String[] args) {
            try {
                MyRemote service = new MyRemoteImpl();
                Naming.rebind("RemoteHello", service);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public String sayHello() throws RemoteException {
            return "Server says,' Hello RMI!'";
        }
    
    }


    或在IDE中run也可

    6、客户端代码及访问服务

    package rmi;
    
    import java.rmi.Naming;
    
    /*2015-8-25*/
    public class MyRemoteClient {
        public static void main(String[] args) {
            new MyRemoteClient().go();
        }
    
        public void go() {
            try {
                MyRemote service = (MyRemote) Naming.lookup("rmi://127.0.0.1/RemoteHello");
                String s = service.sayHello();
                System.out.println("Result:" + s);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }

    结果:

  • 相关阅读:
    解方程
    十进制快速幂
    comb
    题单解题记录-POJ题目分类推荐 (很好很有层次感)
    算法题离谱错误合集
    VMware-Ubuntu16.04踩坑解决记录
    2020牛客多校赛第三场
    需学习的博客地址
    错误记录
    可持久化线段树 区间第k大/小
  • 原文地址:https://www.cnblogs.com/softidea/p/4759044.html
Copyright © 2011-2022 走看看