手撕Java之Rpc调用

参照《分布式服务框架原理与实践-李林锋》的书,

代码调出功能来了。

向更高的服务架构技能进发!

颤抖吧,老IT!

package echorpc;

public interface EchoService {
	String echo(String ping);

}
package echorpc;

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

}
package echorpc;

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 RpcExporter {
	static Executor executor =
			Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

	public static void exporter(String hostName, int port) throws Exception {
		ServerSocket server = new ServerSocket();
		server.bind(new InetSocketAddress(hostName, port));
		try {
			while(true) {
				executor.execute(new ExporterTask(server.accept()));
			}
		} finally {
			server.close();
		}
	}

	private static class ExporterTask  implements Runnable{
		Socket client = null;
		public ExporterTask(Socket client) {
			this.client = client;
		}

		@Override
		public void run() {
			ObjectInputStream input = null;
			ObjectOutputStream output = null;

			try {
				input = new ObjectInputStream(client.getInputStream());
				String interfaceName = input.readUTF();
				Class<?> service = Class.forName(interfaceName);
				String methodName = input.readUTF();
				Class<?>[] parameterTypes = (Class<?>[])input.readObject();
				Object[] arguments = (Object[])input.readObject();
				Method method = service.getMethod(methodName, parameterTypes);
				Object result = method.invoke(service.newInstance(),arguments);
				output = new ObjectOutputStream(client.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 (client != null)
					try {
						client.close();
					} catch(IOException e) {
						e.printStackTrace();
					}
			}

		}

	}

}

package echorpc;

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 RpcImporter<S> {
	@SuppressWarnings("unchecked")
	public S importer(final Class<?> serviceClass, final InetSocketAddress addr) {
		return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(),
				new Class<?>[] {serviceClass.getInterfaces()[0]},
				new InvocationHandler() {

					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						Socket socket = null;
						ObjectOutputStream output = null;
						ObjectInputStream input = null;
						try {
							socket = new Socket();
							socket.connect(addr);
							output = new ObjectOutputStream(socket.getOutputStream());
							output.writeUTF(serviceClass.getName());
							output.writeUTF(method.getName());
							output.writeObject(method.getParameterTypes());
							output.writeObject(args);
							input = new ObjectInputStream(socket.getInputStream());
							return input.readObject();
						} finally {
							if (socket != null)
								socket.close();
							if (input != null)
								input.close();
							if (output != null)
								output.close();

						}

					}

		});
	}

}
package echorpc;

import java.net.InetSocketAddress;

public class echorpc {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					RpcExporter.exporter("localhost", 8088);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		).start();
		RpcImporter<EchoService> importer = new RpcImporter<EchoService>();
		EchoService echo = importer.importer(EchoServiceImpl.class,
				new InetSocketAddress("localhost", 8088));
		System.out.println(echo.echo("Are you all ok?"));

	}

}

时间: 2024-09-18 04:33:10

手撕Java之Rpc调用的相关文章

Java跨语言调用实现方案

Java 跨语言实现方案 背景: 在大型分布式 java 应用中,为了方便开发者,通常底层的 rpc 框架都会做一些调用的封装,让应用层开发人员在开发服务的时候只用编写简单的 pojo 对象就可以了,如流行的 spring remoting , jboss remoting 等等,都有这样的效果. 随着业务的需要,可能上层应用希望采用非 java 技术,如 php , ruby on rails ,而由于 java gc 和内存模型的限制,可能有的底层服务又需要采用更高性能和更加灵活的技术,如果

java 通过axis2 调用.net webservice 时传2维byte数组的问题

问题描述 求大侠解答下java通过axis2调用.netwebservice时.netwebservice入参为一个byte类型的2维数组axis2是支持byte数组的但是2维的byte数组怎么设置入参类型呢下面是传一维byte数组的java客服端代码packagecn.rx.oamp.util;importjava.net.MalformedURLException;importjava.rmi.RemoteException;importjava.util.Date;importjavax.

谈谈JAVA中的调用方式

很多书籍都说Java支持传引用调用的方式,类似于C++中的Person &a引用调用,而近来编程遇到一系列问题让我对此产生了怀疑,于是将这些方法一一列出,我们来一起看看JAVA中的调用方式:   看下面的程序:  class Person {      private String name;//姓名     private String sex;//性别     public Person(String x, String y) {         this.name = x;        

JAVA中对存储过程的调用方法(七) 创建、并在JAVA中直接调用存储过程

七.在JAVA中创建存储过程 并且在JAVA中直接调用 import java.sql.*; public class ProcedureTest { public static void main(String args[]) throws Exception { //加载驱动 DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver()); //获得连接 Connection conn=DriverManager.getCon

Java通过JNI调用C语言的方法

JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能. 解决JAVA对本地操作的一种方法就是JNI. JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式).通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法. 简单介绍及应用如下: 一.JAVA中所需要做的工作 在JAVA程序中,首先需要在类中声明所调

接口-jradius和java项目如何调用

问题描述 jradius和java项目如何调用 请问javaweb项目怎么调用jradius?是不是通过jradius的接口就可以呢?

一个java文件怎么调用另一个文件的text值

问题描述 一个java文件怎么调用另一个文件的text值 例如我在JAVA文件A里面建了一个方法 public String getUser() { String s1; s1=(String)(user.getText()); return s1; } 然后我想在JAVA文件B里调用user.getText()的值,我是这样写的 public InputCardnum inputcardnum;//这是文件A的名字 创建对象 String a=inputcardnum.getUser(); 可

java中对象调用方法返回一个对象的问题

问题描述 java中对象调用方法返回一个对象的问题 例如session.createQuery(hql); 那么这条语句返回的对象属于哪个类呢,如何判断呢? 解决方案 ctrl加鼠标点击createQuery,会有返回方法,或者你在通过session点的时候也可以看到返回方法. 解决方案二: 按住ctrl点击方法,自己去看方法的返回值. 解决方案三: 在java中将一个对象的所有方法打印出来java中远程对象方法调用中的安全策略问题java中返回局部对象问题 解决方案四: 事实上他返回的还是qu

http协议-(实习生,求大神赐教)java httpget来调用自己发布的web service

问题描述 (实习生,求大神赐教)java httpget来调用自己发布的web service public class HelloService { public String sayHello(String username) { return "Hello: " + username; } } 以上是发布的方法,发布后显示的路径是:http://localhost:8080/eclipse4WS/services/HelloService 我的方法名为sayHello() 发布结