自行实现一个简单的RMI

在教主的带领下,完成了一个很简单的RMI工具。就当是练习网络编程吧。

RMI(Remote Method Invocation),远程方法调用。

涉及两个网络端。其核心思想是,一个端可以通过调用另一个端的方法,实现相关功能。
一个端“执行”一个方法,而这个方法的实际执行是在另一端进行的!

要进行远程方法调用,那么,两个端都应该有相同的类,相同的方法。一个端执行一个方法,其实本质是通过调用这个类的代理对象的方法,在其中拦截这个方法,将这个方法的哈希值和参数,通过网络通讯传输给另一端;另一端根据哈希值和参数,能唯一的确定到那个方法,执行完成后将结果返回给对端。

我采用的是短连接,jdk代理。

大致的处理流程:

 我的思路:

建立RPC服务器端:

主要有两个大的步骤:

1、需要给RpcBeanFactory注入方法的哈希值和方法参数(这两个数据相同,就能保证客户机准确的调用远程方法)。

注入的具体分析:

static void doRegist(RpcBeanFactory rpcBeanFactory, Class<?> interfaces, Object object) {
        Method[] methods  = interfaces.getDeclaredMethods();
        for (Method method : methods) {
            String rpcBeanId = String.valueOf(method.toString().hashCode());
            RpcBeanDefination rpcBeanDefination = new RpcBeanDefination();
            rpcBeanDefination.setKlass(interfaces);
            rpcBeanDefination.setMethod(method);
            rpcBeanDefination.setObject(object);

            rpcBeanFactory.AddRpcBean(rpcBeanId, rpcBeanDefination);
        }
    }

通过传过来的接口,得到这个接口中的所有方法,遍历,把每个方法的信息都注入到RpcBeanFactory的Map中。

2、RpcServer需要一直侦听客户机的请求,如果有请求,那么RpcServerExecutor进行具体的处理。

分析:

@Override
    public void run() {
        try {
            // 接收Rpc客户端传递的rpcBeanId和参数
            String rpcBeanId = ois.readUTF();
            Object[] parameters = (Object[]) ois.readObject();
            showParameters(parameters);
            // 定位相关类,对象和方法
            RpcBeanDefination rpcBeanDefination;
            rpcBeanDefination = rpcServer.getRpcBeanFactory().getRpcBean(rpcBeanId);
            // 执行Rpc客户端要求执行的方法
            Method method = rpcBeanDefination.getMethod();
            Object object = rpcBeanDefination.getObject();
            Object result = method.invoke(object, parameters);
            // 向客户端返回执行结果
            oos.writeObject(result);
        } catch (IOException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            closeSocket();
        }
    }

 这是RpcServerExecutor中的处理,接收->定位->执行->返回结果。

建立RPC客户机端:

1、在代理对象的方法中,调用RpcClientExecutor。

/*jdk代理*/
    public Object getProxy(Class<?> klass) {
        // 判断klass是否是接口,若不是,则应该采用cglib代理模式
        return Proxy.newProxyInstance(klass.getClassLoader(), new Class<?>[] { klass }, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String rpcBeanId = String.valueOf(method.toString().hashCode());
                Object result = rpcClientExecutor.rpcExecutor(rpcBeanId, args);

                return result;
            }
        });
    }

 给方法生成哈希值,调用rpcExecutor。

2、执行RpcClientExecutor。

<T> T rpcExecutor(String rpcBeanId, Object[] para) throws IOException, ClassNotFoundException {
        Socket socket = new Socket(rpcServerIp, rpcServerPort);
        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        // 给RPC服务器发送rpcBeanId和参数
        oos.writeUTF(rpcBeanId);
        oos.writeObject(para);
        // 接收RPC服务器执行的结果,并返回
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
        Object result = ois.readObject();

        closeSocket(ois, oos, socket);

        return (T) result;
    }

客户端处理很简单:发送信息->接收信息。

源码链接:

https://github.com/yangchaoy259189888/A-simple-implementation-of-RMI/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值