zoukankan      html  css  js  c++  java
  • [编织消息框架][消息服务]rmi

     RMI(即Remote Method Invoke 远程方法调用)

    • 远程对象: 用于远程客户端调用 必需继承java.rmi.Remote,每个调用方法必须添加java.rmi.RemoteException异常

    • 远程对象实现:用于远程服务器,实现调用逻辑 必需继承UnicastRemoteObject

    • 远程服务器:通过LocateRegistry注册服务

    • 远程客户端:通过LocateRegistry查找服务,调用方法即可发送内容 Naming是LocateRegistry的辅助工具类

    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface ITestRMIService extends Remote {
        //必须加RemoteException否则运行出错: java.rmi.server.ExportException
        public String a(String content) throws RemoteException;
        
        public TestRMIObj b(TestRMIObj input) throws RemoteException;
    }
    // UnicastRemoteObject用于导出的远程对象和获得与该远程对象通信的存根。否则运行出错:java.rmi.MarshalException
    public class TestRMIServiceImpl extends UnicastRemoteObject implements ITestRMIService {
        private static final long serialVersionUID = -6460154344452562895L;
    
        public TestRMIServiceImpl() throws RemoteException {
            super();
        }
    
        @Override
        public String a(String content) {
            System.out.println("call : a"+ content );
            return "server >> " + content;
        }
    
        @Override
        public TestRMIObj b(TestRMIObj input) throws RemoteException {
            System.out.println("call b : "+ input.getB().length );
            input.setA(12);
            return input;
        }
    }
    //必须实现Serializable该对象要支持 Serializable
    public class TestRMIObj implements Serializable {
    
        private static final long serialVersionUID = 2367853017282270281L;
        private int a;
        private Integer[] b;
    
        public int getA() {
            return a;
        }
    
        public Integer[] getB() {
            return b;
        }
    
        public void setA(int a) {
            this.a = a;
        }
    
        public static TestRMIObj of(int a, Integer... b) {
            TestRMIObj ret = new TestRMIObj();
            ret.a = a;
            ret.b = b;
            return ret;
        }
    }
    public class ServerRMI {
        public static void main(String[] args) {
            try {
                // 实例化实现了IService接口的远程服务ServiceImpl对象
                ITestRMIService service02 = new TestRMIServiceImpl();
                // 本地主机上的远程对象注册表Registry的实例,并指定端口为8888
                LocateRegistry.createRegistry(8888);
                // 把远程对象注册到RMI注册服务器上,并命名为service02
                // 绑定的URL标准格式为:rmi://host:port/name
                Naming.bind("rmi://localhost:8888/service02", service02);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            System.out.println("服务器向命名表注册了1个远程服务对象!");
        }
    }
    public class ClientRMI {
        private ITestRMIService service;
    
        public void start() {
            String url = "rmi://localhost:8888/";
            try {
                // 在RMI服务注册表中查找名称为service02的对象,并调用其上的方法
                service = (ITestRMIService) Naming.lookup(url + "service02");
                System.out.println(service.a("你好!"));
                System.out.println(service.b(TestRMIObj.of(1, 2, 3, 4)).getA());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            ClientRMI rmi = new ClientRMI();
            rmi.start();
            while (true) {
                Thread.sleep(500);
                rmi.service.a("a");
            }
        }
    }

    使用rmi开发网络通信非常简单,代码量比写model还少,开发者不需要考虑对象序列化,网络IO模型,粘包/半包、传输协议等问题

    但它应用场景非常少,不适合大规模的应用,比较适合s/s服务间调用,原因是对象序列化数据量大,采用的是BIO模型

    RMI与RPC有什么区别呢

    RPC(Remote Procedure Call Protocol)远程过程调用协议

    程序可使用这种协议向网络中的另一台计算机上的程序请求服务。由于使用 RPC 的程序不必了解支持通信的网络协议的情况,因此 RPC 提高了程序的互操作性。在 RPC 中,发出请求的程序是客户程序,而提供服务的程序是服务器

    可以这样理解rmi是sun公司基于rpc制定的实现标准

  • 相关阅读:
    WinCC的电子签名与审计追踪 2.0
    如何在VB脚本中Ping IP
    如何在WinCC中管理Windows账户
    配置SQL Server维护计划-定时备份
    修改SQL Server中的计算机名
    WinCC的画面使用技巧
    用VB脚本复制文件夹并跳过重复文件
    如何在WinCC的VB脚本内实现延时功能
    用vbs和ADSI管理Windows账户
    oracle ROW_NUMBER() OVER(PARTITION BY '分组' ORDER BY '排序' DESC) 用法
  • 原文地址:https://www.cnblogs.com/solq111/p/6734900.html
Copyright © 2011-2022 走看看