手撕Java之Rpc调用

146 阅读2分钟
原文链接: click.aliyun.com

手撕Java之Rpc调用

天飞 2017-12-17 11:03:17 浏览21 评论0

RPC java Server string static exception class void Ping Socket service input

摘要: 参照《分布式服务框架原理与实践-李林锋》的书, 代码调出功能来了。 向更高的服务架构技能进发! 颤抖吧,老IT!

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

代码调出功能来了。

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


颤抖吧,老IT!

030252cd992f66f05988b07b41434c766b47a03e



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?"));

	}

}

4b98d404e941bfde7a2251037b2258545cfd7e19
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

用云栖社区APP,舒服~

【云栖快讯】中办国办印发《推进互联网协议第六版(IPv6)规模部署行动计划》加快推进基于 IPv6 的下一代互联网规模部署,计划指出2025年末中国 IPv6 规模要达到世界第一,阿里云也第一时间宣布了将全面提供IPv6服务,那么在全面部署 IPV6 前,你需要了解都在这儿  详情请点击 评论文章 (0) (0) (0)

相关文章

网友评论