文档章节

简单的RPC框架

james_you
 james_you
发布于 2014/05/23 16:37
字数 840
阅读 641
收藏 10

梁飞哥在他的博客里面做了个简洁的Rpc框架小例子,俺改了下,做成支持注册多个服务的

RpcFramework的代码如下

package net.rpc;

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.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
/**
 * RpcFramework
 * 
 * @author 
 */
public class RpcFramework {
    private static HashMap<String, Object> serviceMap = new HashMap<String, Object>();
    /**
     * 注册服务
     * 相同的服务只会注册一次,后续注册无效
     * 
     * @param service服务
     * @throws Exception
     * */
    public static void registerService(final Object service,final String serviceName) throws Exception{
        if(service == null){
            throw new IllegalArgumentException("service instance == null");
        }
        if(!serviceMap.containsKey(serviceName)){
            serviceMap.put(serviceName, service);
            System.out.println("Register service " + serviceName);
        }else{
            System.out.println("service instance had exists");
        }
        
    }
    /**
     * 启动服务
     * @param port 服务端口
     * @throws Exception
     * */
    public static void startMultiService(int port) throws Exception{
        if (port <= 0 || port > 65535){
            throw new IllegalArgumentException("Invalid port " + port);
        }
        ServerSocket server = new ServerSocket(port);
        while(true){
            try{
                final Socket socket = server.accept();
                new Thread(new Runnable(){
                    @Override
                    public void run() {
                        try
                        {
                            try
                            {
                                //读取客户端信息
                                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                                try
                                {
                                    String serviceName = input.readUTF();
                                    String methodName = input.readUTF();
                                    Class<?>[] parameterTypes = (Class<?>[])input.readObject();
                                    Object[] arguments = (Object[])input.readObject();
                                    //将信息写回客户端
                                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                                    try
                                    {
                                        Object service = serviceMap.get(serviceName);
                                        System.out.println(service==null?"服务为空":"call service"+service.getClass().getName());
                                        Method method = service.getClass().getMethod(methodName, parameterTypes);
                                        Object result = method.invoke(service, arguments);
                                        output.writeObject(result);
                                    }catch (Throwable t) {
                                        output.writeObject(t);
                                    }finally{
                                        output.close();
                                    }
                                }finally{
                                    input.close();
                                }
                            }finally{
                                socket.close();
                            }
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                }).start();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 引用服务(多服务接口)
     * 
     * @param <T> 接口泛型
     * @param interfaceClass 接口类型
     * @param host 服务器主机名
     * @param port 服务器端口
     * @return 远程服务
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static <T> T refer4MultiService(final Class<T> interfaceClass,final String host,final int port) throws Exception
    {
        if(interfaceClass == null){
            throw new IllegalArgumentException("Interface class == null");
        }
        if(!interfaceClass.isInterface()){
            throw new IllegalArgumentException("The " + interfaceClass.getName() + " must be interface class!");
        }
        if(host==null || host.length()==0){
            throw new IllegalArgumentException("Host == null!");
        }
        if(port<=0 || port >65535){
            throw new IllegalArgumentException("Invalid port " + port);
        }
        System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, new InvocationHandler(){
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                Socket socket = new Socket(host,port);
                try{
                    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                    try
                    {
                        //向服务端发送数据
                        output.writeUTF(interfaceClass.getName());
                        output.writeUTF(method.getName());
                        output.writeObject(method.getParameterTypes());
                        output.writeObject(args);
                        //获取服务端响应
                        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                        try
                        {
                            Object result = input.readObject();
                             if (result instanceof Throwable) {
                                    throw (Throwable) result;
                                }
                                return result;
                        }finally{
                            input.close();
                        }
                    }finally{
                        output.close();
                    }
                    
                }finally{
                    socket.close();
                }
            }
        });
    }
}

MultiRpcProvider 服务提供者

package net.rpc;

public class MultiRpcProvider {

    /**
     * @throws Exception  
     * @Title: 暴露服务 
     * @Description: TODO(这里用一句话描述这个方法的作用) 
     * @param @param args    设定文件 
     * @return void    返回类型 
     * @throws 
     */
    public static void main(String[] args) throws Exception {
        //注册服务
        HelloService helloService = new HelloServiceImpl();  
        RpcFramework.registerService(helloService,HelloService.class.getName());
        UserRegister registerService = new UserRegisterImpl();
        RpcFramework.registerService(registerService,UserRegister.class.getName());
        //启动服务
        RpcFramework.startMultiService(1234);
    }
}

MultiRpcConsumer 服务消费者

package net.rpc;

public class MultiRpcConsumer {

    /**
     * @throws Exception  
     * @Title: RPC服务调用 
     * @Description: TODO(这里用一句话描述这个方法的作用) 
     * @param @param args    设定文件 
     * @return void    返回类型 
     * @throws 
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        HelloService helloService = RpcFramework.refer4MultiService(HelloService.class, "127.0.0.1", 1234);
        for(int i=0;i<10;i++){
            String hello = helloService.hello("World "+i);
            System.out.println(hello);
        }
        UserRegister registerService = RpcFramework.refer4MultiService(UserRegister.class, "127.0.0.1", 1234);
        for(int i=0;i<10;i++){
            User u = new User();
            u.setUserName("Mr"+i);
            u.setAge(i);
            String userInfo = registerService.register(u);
            System.out.println(userInfo);
        }
    }
}

定义服务接口

package net.rpc;
/**
 * HelloService
 * 定义服务接口  
 */
public interface HelloService {

    String hello(String name);

}
package net.rpc;

public interface UserRegister {
    public String register(User u);
    public String registerUs(String name);
}

接口实现

package net.rpc;

/**
 * 实现服务
 * */
public class HelloServiceImpl implements HelloService{
    @Override
    public String hello(String name) {
        // TODO Auto-generated method stub
        return "hello "+name;
    }
}
package net.rpc;

public class UserRegisterImpl implements UserRegister {
    @Override
    public String registerUs(String name) {
        // TODO Auto-generated method stub
        return "name:"+name;
    }
    @Override
    public String register(User u) {
        // TODO Auto-generated method stub
        return "name:"+u.getUserName()+"- age:"+u.getAge();
    }

}
package net.rpc;

import java.io.Serializable;
/**
* 注意实现Serializable接口
*/
public class User implements Serializable{
    private static final long serialVersionUID = -8878453222212794683L;
    private String userName;
    private int age;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
}


© 著作权归作者所有

上一篇: NIO通信例子
下一篇: JUC学习之ThreadPool
james_you
粉丝 5
博文 25
码字总数 12119
作品 0
长宁
技术主管
私信 提问
轻量级rpc框架--bbossgroups RPC

bbossgroups RPC 是基于bbossaop的轻量级rpc框架,感兴趣的朋友可以用一用。bbossgroups提供的RPC框架是bboss aop子项目中一个子模块,具有以下特点: 1.支持多种通讯协议jms,jgroups,min...

bboss
2010/04/07
2.2K
0
什么样的 RPC 才是好用的 RPC

现在RPC框架很多,但是真正好用的RPC却是少之又少。那么什么是好用的RPC,什么是不好用的RPC呢,有一个评判标准吗?下面是我列举出来的衡量RPC好用与否的几条标准: 真的像本地函数一样调用 ...

局长
2016/09/06
10.2K
42
Thrift RPC 框架分析

前言 工作中用到Thrift,一直想深入研究一下。今天这篇博客以提问的方式,分析Thrift的源码。文章部分参考自:Thrift源码分析。 本来计划的题目是:「Thrift RPC 源码分析」,可是写了两个小...

被称为L的男人
2018/12/01
0
0
为什么需要RPC,而不是简单的HTTP接口

有个问题想请教OSC的大神,请不吝赐教。 目前有很多Java的RPC框架,有基于Json的,有基于XML,也有基于二进制对象的。 论复杂度,RPC框架肯定是高于简单的HTTP接口的。但毋庸置疑,HTTP接口由...

清风-蓝魔泪
2016/03/06
22.7K
25
bbossgroups RPC 基于aop的轻量级rpc框架

bbossgroups RPC 基于aop的轻量级rpc框架 收藏 bbossgroups RPC 是基于bbossaop的轻量级rpc框架,感兴趣的朋友可以用一用。bbossgroups提供的RPC框架是bboss aop子项目中一个子模块,具有以下...

yin_bp
2010/04/06
30
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
7
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
7
0
Flutter系列之在 macOS 上安装和配置 Flutter 开发环境

本文为Flutter开发环境在macOS下安装全过程: 一、系统配置要求 想要安装并运行 Flutter,你的开发环境需要最低满足以下要求: 操作系统:macOS(64位) 磁盘空间:700 MB(不包含 IDE 或其余...

過愙
昨天
6
0
OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
昨天
2.6K
16
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
昨天
42
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部