美文网首页
JAVA中如何实现基于TCP协议的RPC调用?

JAVA中如何实现基于TCP协议的RPC调用?

作者: 沧海一束 | 来源:发表于2016-09-05 14:53 被阅读0次

    使用Java语言的Socket API,我们能够实现一个简单的RPC调用,在这个例子中,包括了服务的接口及接口的远端实现、服务的消费者与远端的提供方。基于TCP协议所实现的RPC的类图:

    1463890335757166139.jpg

    服务的接口和实现都非常简单,它提供了一个SayHello方法,它有一个String类型的参数,通过该参数来识别究竟是返回hello还是返回byebye,代码如下:

    pulic interface SayHelloService {
    /**
     *问好的接口
     *@param helloArg 参数
     *@retrun
     */
    public String sayHello(String helloArg);
    }
    

    服务的实现:

    public class SayHelloServiceImpl implements SayHelloService {
    @Override
    public String sayHello(String helloArg) {
        if(helloArg.equls("hello")) {
            return "hello";
        } else {
            return "bye bye";
        }
    }
    }
    

    服务消费者Consumer类的部分关键代码:

    //接口名称
     String interfacename = SayHelloService.class.getName();
    //需要远程执行的方法
    Method method = SayHelloService.class.getMethod("sayHello", java.lang.String.class);
    //需要传递到远端的参数
    Object[] arguments = {"hello"};
    Socket socket = new Socket("127.0.0.1", 1234);
    ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
    output.writeUTF(interfacename); //接口名称
    output.writeUTF(method.getName()); //方法名称
    output.writeObject(method.getParameterTypes());
    output.writeObject(arguments);
    
    //从远端读取方法执行结果
    ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
    Object result = input.readObject();
    

    先取得接口的名称、需求调用的方法和需要传递的参数,并通过Socket将其发送到服务提供方,等待服务端响应结果。此处为了便于演示,使用的是阻塞式I/O,实际的生产环境中出于性能考虑,往往使用非阻塞式I/O,以提高更大的吞吐量。

    服务提供者Provider类的部分关键代码:

    ServiceSocket server = new ServiceSocket(1234);
    while(true) {
     Socket socket = service.accept();
      //读取服务信息
     ObjectInputStream input = new ObjectInputStream(scoket.getInputStream());
     String interfacename = input.readUTF(); //接口名称
     String methodName = input.readUTF(); //方法名称
     Class<?>[] parameterTypes = (Class<?>[])input.readObject(); //参数类型
     Object[] arguments = (Object[])input.readObject(); //参数对象
    //执行调用
    Class serviceinterfaceclass = Class.forName(interfacename); //得到接口的class
    Object service services.get(interfacename); //得到服务实现的对象
    Method method = serviceinterfaceclass.getMethod(methodName, parameterTypes);//获得要调用的方法
    Object result = method.invoke(service, arguments);
    ObjectOutputString output = new ObjectOutputStream(socket.getOutputStream());
    output.writeObject(result);
    }
    

    服务提供端事先将服务实例化好后房租service这个Map中(此次涉及服务的路由,被简化了,在以后的文章中会做出说明),通过一个while循环,不断地接收新到来的请求,得到所需要的参数,包括接口名称、方法名称、参数类型和参数,通过java的反射取得接口中需求调用的方法,执行后将结果返回给服务的消费者。

    在真实的生产环境中,常常是多个客服端同时发送多个请求道服务器,服务端则需要实现同时接收和处理多个客服端的请求,涉及并发处理、服务路由、复杂均衡等。

    原文链接:http://www.javaseo.cn/article/37/

    相关文章

      网友评论

          本文标题:JAVA中如何实现基于TCP协议的RPC调用?

          本文链接:https://www.haomeiwen.com/subject/diurettx.html