`
id.alex
  • 浏览: 22974 次
社区版块
存档分类
最新评论

一个最简单的 RPC 程序

    博客分类:
  • Java
阅读更多
一个最简单的 RPC 程序.

Service 接口
public interface Service {
	String sayHello(String name);
	
	String sayJoke();
}


Service 实现类
public class ServiceImpl implements Service {
	@Override
	public String sayHello(String name) {
		return "Hello " + name;
	}

	@Override
	public String sayJoke() {
		return "一姐姐半夜打黑车回家,开了后门后,想还是记下车牌吧,于是关门绕到车位看了一眼,结果车开跑了。姐姐心想司机心虚了,还好没坐这车。于是继续等,十分钟后,那黑车又绕回来停在姐姐身边摇下车窗说:你怎么没上来啊,我听关车门以为你上来了,问你去哪儿,一回头没人,这大半夜的吓死我了...(转)";
	}
}


Server 端
@SuppressWarnings("rawtypes")
public class Server {

	private final Logger logger = LoggerFactory.getLogger(Server.class);

	private final Map<Class, Object> serviceMap = new ConcurrentHashMap<>();

	public void start(int port) {
		ServerRunnable pr = new ServerRunnable(port);
		pr.start();
		logger.info("Publisher start!");
	}

	public <T> void publishService(Class<T> service, T impl) {
		serviceMap.put(service, impl);
	}

	private class ServerRunnable extends Thread {

		private int port;
		private ServerSocket ss = null;

		public ServerRunnable(int port) {
			this.port = port;
		}

		@Override
		public void run() {

			try {
				ss = new ServerSocket(port);
			} catch (IOException e) {
				logger.error("", e);
			}

			while (true) {
				Socket s = null;
				try {
					logger.info("accept");
					s = ss.accept();
				} catch (IOException e) {
					logger.error("", e);
				}

				ServerHandler handler = new ServerHandler(s, serviceMap);
				handler.start();
			}
		}
	}

	private class ServerHandler extends Thread {

		private Socket s;

		public ServerHandler(Socket s, Map<Class, Object> serviceMap) {
			this.s = s;
		}

		@Override
		public void run() {

			ObjectInputStream ois = null;
			ObjectOutputStream oos = null;
			try {
				// 主要的逻辑在这了,
				ois = new ObjectInputStream(s.getInputStream());
				Class service = (Class) ois.readObject();
				Object serviceImpl = serviceMap.get(service);
				if (serviceImpl != null) {
					String methodName = ois.readUTF();
					Class[] parameterTypes = (Class[]) ois.readObject();
					Object[] args = (Object[]) ois.readObject();

					Method method = serviceImpl.getClass().getMethod(methodName, parameterTypes);
					Object result = method.invoke(serviceImpl, args);

					oos = new ObjectOutputStream(s.getOutputStream());
					oos.writeObject(result);
					oos.flush();
					logger.info("RPC handle finish");
				} else {
					logger.warn("Service implement not found!");
				}

			} catch (Exception e) {
				logger.error("", e);
			} finally {
				if (ois != null) {
					try {
						ois.close();
					} catch (IOException e) {
					}
				}

				if (oos != null) {
					try {
						oos.close();
					} catch (IOException e) {
					}
				}

				if (s != null) {
					try {
						s.close();
					} catch (IOException e) {
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		Server server = new Server();
		server.start(10001);
		server.publishService(Service.class, new ServiceImpl());
	}
}



Client 端

public class Client {

	private static final Logger logger = LoggerFactory.getLogger(Client.class);

	@SuppressWarnings("unchecked")
	public <T> T getProxy(final String host, final int port, Class<T> service) {

		InvocationHandlerImpl<T> handler = new InvocationHandlerImpl<T>(service, host, port);
		Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { Service.class }, handler);

		return (T) proxy;
	}

	private class InvocationHandlerImpl<T> implements InvocationHandler {

		private Class<T> service;
		private String host;
		private int port;

		public InvocationHandlerImpl(Class<T> service, String host, int port) {
			super();
			this.service = service;
			this.host = host;
			this.port = port;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			Socket s = null;
			ObjectInputStream ois = null;
			ObjectOutputStream oos = null;
			try {
				s = new Socket(host, port);
				oos = new ObjectOutputStream(s.getOutputStream());
				oos.writeObject(service);
				oos.writeUTF(method.getName());
				oos.writeObject(method.getParameterTypes());
				oos.writeObject(args);
				oos.flush();

				ois = new ObjectInputStream(s.getInputStream());
				return ois.readObject();
			} catch (Exception e) {
				logger.error("", e);
				return null;
			} finally {
				if (ois != null) {
					try {
						ois.close();
					} catch (IOException e) {
					}
				}
				if (oos != null) {
					try {
						oos.close();
					} catch (IOException e) {
					}
				}
				if (s != null) {
					try {
						s.close();
					} catch (IOException e) {
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		Client c = new Client();
		Service service = c.getProxy("localhost", 10001, Service.class);

		System.out.println( service.sayHello("World"));
		System.out.println( service.sayJoke());

	}
}

分享到:
评论

相关推荐

    最简单的RPC框架源码.zip

    通过对"最简单的RPC框架源码"的分析,我们可以学习到如何设计和实现一个基本的RPC框架,理解其工作流程和核心组件。这将有助于我们更好地理解和使用复杂的RPC框架,如Dubbo、gRPC、Spring Cloud等。

    Hessian远程调用RPC最简单demo

    本教程将详细介绍"Hessian远程调用RPC最简单demo",包括服务器端服务发布和客户端服务调用的实现,以及所需资源。 首先,我们来看一下`hessian-4.0.7.jar`这个文件。这是Hessian库的核心组件,包含了实现Hessian...

    android-json-rpc

    1. **简单易用的API**:android-json-rpc提供了一个直观且易于理解的API,使得开发者能够快速地集成到项目中,进行JSON-RPC的调用。通过创建一个`JsonRpcClient`实例,然后调用其`call`方法,可以方便地发送请求并...

    RPC(远程调用)的资料

    在RPC中,客户端发起一个调用,参数通过RPC传输层(可以是TCP或UDP,即TI-RPC)传递到服务器,然后根据预设的目的地址和RPC应用程序号找到对应的服务器。服务器接收到请求后,执行相应的操作并将结果返回给客户端。...

    rpc.rar_it_rpc_rpc linux

    在IT领域,RPC使得一个程序可以调用另一个在不同系统或者网络中的程序,就像调用本地函数一样简单,极大地简化了分布式系统的设计。本压缩包文件"rpc.rar"涉及的关键词是"rpc"以及"linux",表明内容可能与Linux系统...

    phprpc中文文档

    RPC是一种分布式计算技术,允许程序在不关心远程系统具体实现的情况下调用另一个网络上的程序或服务。Phprpc就是基于此理念,为PHP开发的RPC解决方案。 2. **Phprpc框架架构** Phprpc框架由服务端和服务端客户端...

    手写rpc的项目

    现在,我们来谈谈如何手写一个简单的RPC框架: 1. **定义接口**:首先,定义一个公共接口,这是客户端和服务端共同遵循的契约。 2. **服务实现**:服务提供者实现接口,并启动监听服务,等待客户端连接。 3. **...

    xml-rpc学习心得

    通过本文的学习心得分享,我们可以了解到XML-RPC的基本原理以及如何构建一个简单的XML-RPC客户端和服务端。在实际开发过程中,根据具体的需求选择合适的Transport Factory是非常重要的一步。此外,对于服务端的开发...

    JSON-RPC 1.0 & 2.0 in Python

    例如,使用`jsonrpc-stdlib`,你可以这样定义一个简单的服务: ```python from jsonrpcserver import method, serve @method def add(a, b): return a + b serve() ``` **客户端调用** 客户端则可以通过发送...

    python实现一个简单RPC框架的示例

    RPC(Remote Procedure Call)是一种进程间通信的技术,允许程序调用另一个远程计算机上的函数或方法,就像调用本地函数一样。在Python中实现一个简单的RPC框架,我们可以利用Python的socket库来处理网络通信,以及...

    RPC远程过程调用详细讲解

    RPC的设计目标是提供一个透明的、简单的编程接口,使开发人员能够轻松地构建分布式应用。 #### 二、RPC基础概念 在客户-服务器模型中,进程之间的交互由一个进程发起请求并等待响应,而另一个进程接收请求并发送...

    用RPC机制把本地调用转换成远程调用

    在给定的示例中,作者蒋维提供了一个简单的本地程序`printfmsg.c`,该程序的功能是在控制台上打印一条消息。接下来,我们探讨如何将其中的`printmessage()`函数转换为可通过RPC调用的远程函数。 ##### 定义远程过程...

    jax_rpc webservices hander头增加用户密码

    JAX-RPC(Java API for XML-based Remote Procedure Calls)是Java平台上的一个标准,它为创建和使用Web服务提供了简单且直观的API。本篇文章将深入探讨如何在JAX-RPC Web服务处理程序(handler)中添加用户密码,以...

    rpc.rar_RPC program_rpc

    在RPC机制中,客户端发起一个调用请求,这个请求包含了想要执行的服务(在服务器端的函数或方法)以及必要的参数。然后,RPC框架负责将这个调用转换为网络消息,并将其发送到服务器。服务器接收到消息后,解析出请求...

    RPC.rar_java rpc

    RPC(Remote Procedure Call)是一种分布式计算技术,允许一个程序在一台计算机上执行远程服务器上的代码,就像调用本地函数一样简单。在这个“RPC.rar_java rpc”压缩包中,我们可以推测包含的是一个Java实现的RPC...

    WebServices服务接口调用---基于rpc方式应用

    在实际应用中,我们首先会创建一个SEI,它包含了Web服务需要暴露的方法。然后,使用JAX-WS工具(如wsimport或JAXB)自动生成服务端和客户端的 stubs。接着,编写服务实现类,该类实现了SEI并提供实际业务逻辑。最后...

    为什么说要搞定微服务架构,先搞定RPC框架

    **RPC(Remote Procedure Call Protocol,远程过程调用协议)**是一种通信协议,允许一个程序调用另一个位于不同地址空间的程序,通常是通过网络,而无需了解底层网络细节。RPC的目标是使得远程过程调用如同本地调用...

    JSON-RPC for Java使用说明.doc

    JSON-RPC for Java 使用说明 JSON-RPC(JavaScript Remote Procedure Call)是一种轻量级的远程过程调用(RPC...JSON-RPC for Java 是一个功能强大、轻量级的远程过程调用解决方案,非常适合在 Java 应用程序中使用。

    一款python的rpc服务

    标题提及的"一款python的rpc服务"很可能是指Hprose,一个轻量级、高性能、易于使用的跨语言RPC框架。Hprose支持多种编程语言,包括Python,这使得它非常适合构建跨平台、跨语言的分布式应用。 首先,我们需要理解...

    rpc-demo.zip

    在这个“rpc-demo.zip”压缩包中,你将找到一个简单的RPC实现,它是基于Spring框架和服务的动态发布,同时使用了底层的Socket通信。下面我们将深入探讨这个实例中的关键知识点。 首先,RPC的核心思想是透明性,即...

Global site tag (gtag.js) - Google Analytics