招聘室内设计,网站seo查询站长之家,保定哪里做网站,怀柔广州网站建设原帖地址 感谢 作者 http://blog.csdn.net/rulon147/article/details/53814589 一、什么是RPC RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的…
原帖地址 感谢 作者 http://blog.csdn.net/rulon147/article/details/53814589
一、什么是RPC
?
?
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。 RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。 有多种 RPC模式和执行。最初由 Sun 公司提出。IETF ONC 宪章重新修订了 Sun 版本,使得 ONC RPC 协议成为 IETF 标准协议。现在使用最普遍的模式和执行是开放式软件基础的分布式计算环境(DCE)。?
?
二、图例说明
?
三、java 实例演示
1、实现技术方案
?
???? 下面使用比较原始的方案实现RPC框架,采用Socket通信、动态代理与反射与Java原生的序列化。
?
2、RPC框架架构
? ? ?RPC架构分为三部分:
?
- 服务提供者,运行在服务器端,提供服务接口定义与服务实现类。
- 服务中心,运行在服务器端,负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。
- 服务消费者,运行在客户端,通过远程代理对象调用远程服务。
?
?
?
?
?
3、 具体实现
?
?
?
1)服务提供者接口定义与实现,代码如下:
[java]?view plaincopy- package?services;??
- ??
- ??
- public?interface?HelloService?{??
- ??
- ??
- ????String?sayHi(String?name);??
- ??
- ??
- }??
2)HelloServices接口实现类:
?
[java]?view plaincopy- package?services.impl;??
- ??
- ??
- import?services.HelloService;??
- ??
- ??
- public?class?HelloServiceImpl?implements?HelloService?{??
- ??
- ??
- ????public?String?sayHi(String?name)?{??
- ????????return?"Hi,?"?+?name;??
- ????}??
- ??
- ??
- }??
?
3)服务中心代码实现,代码如下:
[java]?view plaincopy- package?services;??
- ??
- ??
- import?java.io.IOException;??
- ??
- ??
- public?interface?Server?{??
- ????public?void?stop();??
- ??
- ??
- ????public?void?start()?throws?IOException;??
- ??
- ??
- ????public?void?register(Class?serviceInterface,?Class?impl);??
- ??
- ??
- ????public?boolean?isRunning();??
- ??
- ??
- ????public?int?getPort();??
- }??
4)服务中心实现类:
?
[java]?view plaincopy- package?services.impl;??
- ??
- ??
- ??
- ??
- ??
- ??
- 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.HashMap;??
- import?java.util.concurrent.ExecutorService;??
- import?java.util.concurrent.Executors;??
- ??
- ??
- import?services.Server;??
- ??
- ??
- public?class?ServiceCenter?implements?Server?{??
- ????private?static?ExecutorService??????????????executor????????=?Executors.newFixedThreadPool(Runtime.getRuntime()??
- ????????????????????????????????????????????????????????????????????????.availableProcessors());??
- ??
- ??
- ????private?static?final?HashMap
?serviceRegistry?=?new?HashMap ();?? - ??
- ??
- ????private?static?boolean??????????????????????isRunning???????=?false;??
- ??
- ??
- ????private?static?int??????????????????????????port;??
- ??
- ??
- ????public?ServiceCenter(int?port)?{??
- ????????this.port?=?port;??
- ????}??
- ??
- ??
- ????public?void?stop()?{??
- ????????isRunning?=?false;??
- ????????executor.shutdown();??
- ????}??
- ??
- ??
- ????public?void?start()?throws?IOException?{??
- ????????ServerSocket?server?=?new?ServerSocket();??
- ????????server.bind(new?InetSocketAddress(port));??
- ????????System.out.println("start?server");??
- ????????try?{??
- ????????????while?(true)?{??
- ????????????????//?1.监听客户端的TCP连接,接到TCP连接后将其封装成task,由线程池执行??
- ????????????????executor.execute(new?ServiceTask(server.accept()));??
- ????????????}??
- ????????}?finally?{??
- ????????????server.close();??
- ????????}??
- ????}??
- ??
- ??
- ????public?void?register(Class?serviceInterface,?Class?impl)?{??
- ????????serviceRegistry.put(serviceInterface.getName(),?impl);??
- ????}??
- ??
- ??
- ????public?boolean?isRunning()?{??
- ????????return?isRunning;??
- ????}??
- ??
- ??
- ????public?int?getPort()?{??
- ????????return?port;??
- ????}??
- ??
- ??
- ????private?static?class?ServiceTask?implements?Runnable?{??
- ????????Socket?clent?=?null;??
- ??
- ??
- ????????public?ServiceTask(Socket?client)?{??
- ????????????this.clent?=?client;??
- ????????}??
- ??
- ??
- ????????public?void?run()?{??
- ????????????ObjectInputStream?input?=?null;??
- ????????????ObjectOutputStream?output?=?null;??
- ????????????try?{??
- ????????????????//?2.将客户端发送的码流反序列化成对象,反射调用服务实现者,获取执行结果??
- ????????????????input?=?new?ObjectInputStream(clent.getInputStream());??
- ????????????????String?serviceName?=?input.readUTF();??
- ????????????????String?methodName?=?input.readUTF();??
- ????????????????Class>[]?parameterTypes?=?(Class>[])?input.readObject();??
- ????????????????Object[]?arguments?=?(Object[])?input.readObject();??
- ????????????????Class?serviceClass?=?serviceRegistry.get(serviceName);??
- ????????????????if?(serviceClass?==?null)?{??
- ????????????????????throw?new?ClassNotFoundException(serviceName?+?"?not?found");??
- ????????????????}??
- ????????????????Method?method?=?serviceClass.getMethod(methodName,?parameterTypes);??
- ????????????????Object?result?=?method.invoke(serviceClass.newInstance(),?arguments);??
- ??
- ??
- ????????????????//?3.将执行结果反序列化,通过socket发送给客户端??
- ????????????????output?=?new?ObjectOutputStream(clent.getOutputStream());??
- ????????????????output.writeObject(result);??
- ????????????}?catch?(Exception?e)?{??
- ????????????????e.printStackTrace();??
- ????????????}?finally?{??
- ????????????????if?(output?!=?null)?{??
- ????????????????????try?{??
- ????????????????????????output.close();??
- ????????????????????}?catch?(IOException?e)?{??
- ????????????????????????e.printStackTrace();??
- ????????????????????}??
- ????????????????}??
- ????????????????if?(input?!=?null)?{??
- ????????????????????try?{??
- ????????????????????????input.close();??
- ????????????????????}?catch?(IOException?e)?{??
- ????????????????????????e.printStackTrace();??
- ????????????????????}??
- ????????????????}??
- ????????????????if?(clent?!=?null)?{??
- ????????????????????try?{??
- ????????????????????????clent.close();??
- ????????????????????}?catch?(IOException?e)?{??
- ????????????????????????e.printStackTrace();??
- ????????????????????}??
- ????????????????}??
- ????????????}??
- ??
- ??
- ????????}??
- ????}??
- ??
- ??
- ??
- ??
- ??
- ??
- }??
?
5)客户端的远程代理对象:
?
[java]?view plaincopy- package?client;??
- ??
- ??
- import?java.io.ObjectInputStream;??
- import?java.io.ObjectOutputStream;??
- import?java.lang.reflect.InvocationHandler;??
- import?java.lang.reflect.Proxy;??
- import?java.net.InetSocketAddress;??
- import?java.net.Socket;??
- import?java.lang.reflect.Method;??
- ??
- ??
- public?class?RPCClient
?{?? - ????@SuppressWarnings("unchecked")??
- ????public?static?
?T?getRemoteProxyObj(final?Class>?serviceInterface,?final?InetSocketAddress?addr)?{?? - ????????//?1.将本地的接口调用转换成JDK的动态代理,在动态代理中实现接口的远程调用??
- ????????return?(T)?Proxy.newProxyInstance(serviceInterface.getClassLoader(),?new?Class>[]?{?serviceInterface?},??
- ????????????????new?InvocationHandler()?{??
- ????????????????????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{??
- ????????????????????????Socket?socket?=?null;??
- ????????????????????????ObjectOutputStream?output?=?null;??
- ????????????????????????ObjectInputStream?input?=?null;??
- ????????????????????????try?{??
- ????????????????????????????//?2.创建Socket客户端,根据指定地址连接远程服务提供者??
- ????????????????????????????socket?=?new?Socket();??
- ????????????????????????????socket.connect(addr);??
- ??
- ??
- ????????????????????????????//?3.将远程服务调用所需的接口类、方法名、参数列表等编码后发送给服务提供者??
- ????????????????????????????output?=?new?ObjectOutputStream(socket.getOutputStream());??
- ????????????????????????????output.writeUTF(serviceInterface.getName());??
- ????????????????????????????output.writeUTF(method.getName());??
- ????????????????????????????output.writeObject(method.getParameterTypes());??
- ????????????????????????????output.writeObject(args);??
- ??
- ??
- ????????????????????????????//?4.同步阻塞等待服务器返回应答,获取应答后返回??
- ????????????????????????????input?=?new?ObjectInputStream(socket.getInputStream());??
- ????????????????????????????return?input.readObject();??
- ????????????????????????}?finally?{??
- ????????????????????????????if?(socket?!=?null)??
- ????????????????????????????????socket.close();??
- ????????????????????????????if?(output?!=?null)??
- ????????????????????????????????output.close();??
- ????????????????????????????if?(input?!=?null)??
- ????????????????????????????????input.close();??
- ????????????????????????}??
- ????????????????????}??
- ????????????????});??
- ????}??
- }??
?
6)最后为测试类:
?
[java]?view plaincopy- package?client;??
- ??
- ??
- import?java.io.IOException;??
- import?java.net.InetSocketAddress;??
- ??
- ??
- import?services.HelloService;??
- import?services.Server;??
- import?services.impl.HelloServiceImpl;??
- import?services.impl.ServiceCenter;??
- ??
- ??
- public?class?RPCTest?{??
- ????public?static?void?main(String[]?args)?throws?IOException?{??
- ????????new?Thread(new?Runnable()?{??
- ????????????public?void?run()?{??
- ????????????????try?{??
- ????????????????????Server?serviceServer?=?new?ServiceCenter(8088);??
- ????????????????????serviceServer.register(HelloService.class,?HelloServiceImpl.class);??
- ????????????????????serviceServer.start();??
- ????????????????}?catch?(IOException?e)?{??
- ????????????????????e.printStackTrace();??
- ????????????????}??
- ????????????}??
- ????????}).start();??
- ????????HelloService?service?=?RPCClient??
- ????????????????.getRemoteProxyObj(HelloService.class,?new?InetSocketAddress("localhost",?8088));??
- ????????System.out.println(service.sayHi("test"));??
- ????}??
- ??
- ??
- }??
?
运行结果:
[java]?view plaincopy- regeist?service?HelloService??
- start?server??
- Hi,?test ?
转载于:https://www.cnblogs.com/juniorMa/p/7530777.html