一个RPC的demo (good)

从下面的例子中可以看到,Consumer(client)的代码中引用了Provider部分的class,本例中是

com.provider.EchoServiceImpl和com.provider.EchoService

即这些class在Consumer(client)和Provider(server)都需要部署

 

Provider:

package com.provider;

public interface EchoService {
    String echo(String msg);
}
package com.provider;

public class EchoServiceImpl implements EchoService {
    @Override
    public String echo(String msg) {
        return msg != null ? msg + "-->I am OK." : " pass null.";
    }
}

 

package com.provider;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class RpcProvider {
    private static Executor executor = Executors.newFixedThreadPool(20);

    public static void provide(String host, int port) throws IOException {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress(host, port));
        try {
            while (true) {
                System.out.println("one input coming");
                executor.execute(new ProviderTask(serverSocket.accept()));
                System.out.println("execute one input");
            }
        } finally {
            serverSocket.close();
        }

    }

    private static class ProviderTask implements Runnable {
        private Socket socket;

        public ProviderTask(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            ObjectInputStream inputStream = null;
            ObjectOutputStream outputStream = null;
            try {
                inputStream = new ObjectInputStream(socket.getInputStream());
                String className = inputStream.readUTF();
                Class<?> service = Class.forName(className);
                String methodName = inputStream.readUTF();
                Class<?>[] parameterTypes = (Class<?>[]) inputStream.readObject();
                Object[] arguments = (Object[]) inputStream.readObject();
                Method method = service.getMethod(methodName, parameterTypes);
                Object result = method.invoke(service.newInstance(), arguments);
                outputStream = new ObjectOutputStream(socket.getOutputStream());
                outputStream.writeObject(result);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                close(inputStream);
                close(outputStream);
                close(socket);
            }
        }

    }

    public static void close(AutoCloseable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

package com.provider;

import java.io.IOException;

public class ProviderMain {
    public static void main(String[] args) {
        try {
            RpcProvider.provide("localhost", 8088);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

Consumer:

package com.consumer;

import com.provider.RpcProvider;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;

public class RpcConsumer {

    public Object consume(Class<?> echoServiceClass, InetSocketAddress socketAddress) {
        return Proxy.newProxyInstance(echoServiceClass.getClassLoader(), new Class<?>[]{echoServiceClass.getInterfaces()[0]}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket socket = null;
                ObjectOutputStream outputStream = null;
                ObjectInputStream inputStream = null;
                try {
                    socket = new Socket();
                    socket.connect(socketAddress);
                    outputStream = new ObjectOutputStream(socket.getOutputStream());
                    outputStream.writeUTF(echoServiceClass.getName());
                    outputStream.writeUTF(method.getName());
                    outputStream.writeObject(method.getParameterTypes());
                    outputStream.writeObject(args);
                    inputStream = new ObjectInputStream(socket.getInputStream());
                    return inputStream.readObject();
                } finally {
                    RpcProvider.close(outputStream);
                    RpcProvider.close(inputStream);
                    RpcProvider.close(socket);
                }
            }
        });
    }

}

 

package com.consumer;

import com.provider.EchoService;
import com.provider.EchoServiceImpl;

import java.net.InetSocketAddress;

public class ConsumerMain {
    public static void main(String[] args) {
        RpcConsumer rpcConsumer = new RpcConsumer();
        EchoService echoService = (EchoService) rpcConsumer.consume(EchoServiceImpl.class, new InetSocketAddress("localhost", 8088));
        System.out.println(echoService.echo(ConsumerMain.class.getCanonicalName()));
    }

}

 

时间: 2024-10-29 17:36:55

一个RPC的demo (good)的相关文章

java-我在菜鸟教程上下载了一个JQuery的Demo,但是无法导入进Eclipse里,如何才能导入呢?

问题描述 我在菜鸟教程上下载了一个JQuery的Demo,但是无法导入进Eclipse里,如何才能导入呢? 是不是因为没有Project文件 解决方案 因为没有.project文件,所以它不是一个java工程,当然无法导入了.可以自己新建一个工程,再把这些文件复制到项目根目录下就可以了. 解决方案二: jquery是js不是java,用不着什么项目,也没有什么编译的过程,在eclipse中打开也就是把它当一个大号的文本编辑器罢了. 解决方案三: Jquery不是用eclipse打开的,Jquer

编程-这是一个计算器的demo,点击del按键灰闪退,大家帮忙看一下,谢谢了

问题描述 这是一个计算器的demo,点击del按键灰闪退,大家帮忙看一下,谢谢了 package com.example.demo; import android.R.string;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.On

安卓-android 新人仿照视频写的一个计算的Demo 对比几次没问题,但是执行 报错求救

问题描述 android 新人仿照视频写的一个计算的Demo 对比几次没问题,但是执行 报错求救 Activity03.java private EditText Ac03textone; private EditText Ac03texttwo; private TextView Ac03viewone; private Button Ac03buttone; @Override protected void onCreate(Bundle savedInstanceState) { supe

本人想做一个下载的demo,每次执行时页面会弹出对话框,“打开”,“保存”,“取消”。我想知道用户点的是哪个,好在后台处理记录信息。求帮助。

问题描述 本人想做一个下载的demo,每次执行时页面会弹出对话框,"打开","保存","取消".我想知道用户点的是哪个,好在后台处理记录信息.求帮助.或者有没相关的插件可以让我得到用户点击的是哪个按钮. 解决方案 解决方案二:点了之后,往后台post消息.解决方案三:就是不知道用户点的是哪个按钮啊.解决方案四:引用1楼skgary的回复: 点了之后,往后台post消息. 顶解决方案五:不知楼主的框是用啥弹得?js还是别的?应该都有获取对应按钮值的

WCF+WF双剑合璧构建微软的SOA系列(一):从一个简单的Demo开始

本系列文章将从实例出发,以实例结尾.由浅入深讲解在我们项目中如何使用WCF和WF.我们会发现使用WCF+WF将造就出其他技术无法达到的高度.最后我会将程序架到云端. 微软.net的3W(WPF.WCF.WF)战略如下图.WCF负责通信,WPF负责界面展示,WF负责处理业务逻辑,如下图. 本系列文章会主要用到上图中的所有技术,但是主要讲述如何使用WCF和WF来实现系统的中间层.看过亮剑的朋友知道李云龙常打胜仗,并不是他懂得很多很多的战争的理论知识,而是来自实战中的经验.所以本系列的文章以实战为核心

微信聊天界面长按消息点更多所有cell右移出现一个钩的Demo

问题描述 大牛们:微信聊天界面长按消息点更多所有cell右移出现一个钩的Demo或者 给点思路! 解决方案 这个需要自己在界面处理~

如何设计一个RPC系统

RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高.但是RPC本身的构成却比较复杂,由于受到编程语言.网络模型.使用习惯的约束,有大量的妥协和取舍之处.本文就是通过分析几种流行的RPC实现案例,提供大家在设计RPC系统时的参考. 由于RPC底层的网络开发一般和具体使用环境有关,而编程实现手段也非常多样化,但不影响使用者,因此本文基本涉及如何实现一个RPC系统. 认识RPC(远程调用) 我们在各种操作系统.编程语言生态圈中,多少

一起谈.NET技术,WCF+WF双剑合璧构建微软的SOA系列(一):从一个简单的Demo开始

本系列文章将从实例出发,以实例结尾.由浅入深讲解在我们项目中如何使用WCF和WF.我们会发现使用WCF+WF将造就出其他技术无法达到的高度.最后我会将程序架到云端. 微软.net的3W(WPF.WCF.WF)战略如下图.WCF负责通信,WPF负责界面展示,WF负责处理业务逻辑,如下图. 本系列文章会主要用到上图中的所有技术,但是主要讲述如何使用WCF和WF来实现系统的中间层.看过亮剑的朋友知道李云龙常打胜仗,并不是他懂得很多很多的战争的理论知识,而是来自实战中的经验.所以本系列的文章以实战为核心

自己实现一个RPC框架

RPC简介 远程调用协议. 有多有用,多普遍就不摆了. 大概过程: 1. 调用客户端句柄,传输参数. 2. 封装参数等消息为网络传输格式传给远程主机 3. 服务器句柄得到消息并解析参数 4. 在服务器段执行要调用的代码,并把结果返回给服务器句柄 5. 服务器句柄封装返回结果并用网络传输给客户端 6. 客户端解析并进行其他处理 可见之问题主要有,通信方式.句柄实现.以及消息封装和解析(序列化及反序列化) RPC 之 通信 直接用Socket走TCP/IP 或者是UDP协议, 例如RMI 走HTTP