实现简单的RPC框架

1.被注册的服务

package remote.procedure.call.server;

public interface HelloService {
	public String sayHi(String name);
}
package remote.procedure.call.server;

public class HelloServiceImpl implements HelloService {

	@Override
	public String sayHi(String name) {
		return "Hi," + name;		
	}
}

2.服务中心

    服务被注册到服务中心。客户也通过服务中心获取服务。

package remote.procedure.call.server;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

public interface ServerCenter {
	public void start();
	public void stop();
	public void register(Class service,Class serviceImpl);
}
package remote.procedure.call.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
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;

public class ServerCenterImpl implements ServerCenter{
	private static HashMap<String,Class> serviceRegister = new HashMap();
	private static int port;
	private static ExecutorService  executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	private static boolean isRunning = false;
	
	public ServerCenterImpl(int port) {
		this.port = port; 
	}
	
	@Override
	public void start() {
		ServerSocket server = null;
		try {
			System.out.print("Server start...");
			server = new ServerSocket();
			server.bind(new InetSocketAddress(port));
			
		} catch (IOException e1) {		
			e1.printStackTrace();
		}
		isRunning = true;
		while(true)
		{		
			Socket socket = null;
			try {
			  socket = server.accept();
			} catch (IOException e) {		
				e.printStackTrace();
			}
			executor.execute(new ServiceTask(socket));
		}	
	}
	
	@Override
	public void stop() {
		isRunning = false;
		executor.shutdown();
	}

	@Override
	public void register(Class service,Class serviceImpl) {		
		serviceRegister.put(service.getName(), serviceImpl);
	}

	private static class ServiceTask implements Runnable{
		private Socket socket;
		public ServiceTask() {
			
		}
		public ServiceTask(Socket socket)
		{
			this.socket = socket;
		}
		@Override
		public void run() {
			ObjectInputStream input = null;
			ObjectOutputStream output = null;				
			try
			{					
				
			    input = new ObjectInputStream(socket.getInputStream());
				String serviceName = input.readUTF();
				String methodName = input.readUTF();
				Class[] parameterTypes = (Class[])input.readObject();
				Object[] args = (Object[])input.readObject();
				
				Class service = serviceRegister.get(serviceName);
				Method method = service.getMethod(methodName, parameterTypes);
				Object result = method.invoke(service.newInstance(), args);
				
				output = new ObjectOutputStream(socket.getOutputStream());
				output.writeObject(result);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				try {
					if(output!=null) output.close();
					if(input!=null) input.close();
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}			
			}			
		}	
	}
}

3.客户端

  Proxy.newProxyInstance()生成动态代理对象,它的第一个参数表示:类加载器(代理哪个对象,传入哪个对象的加载器),第二个参数表示:代理对象拥有的方法。第三个参数表示:动态代理对象,他继承了接口InvocationHandler,并实现invoke()函数。

   invoke()的第一个给参数表示:代理的对象。第二个参数表示:代理的方法。第三个对象表示:代理的方法。

package remote.procedure.call.client;

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 Client {
	public static <T>T getRemoteProxyObj(Class service,InetSocketAddress addr)
	{
		return (T)Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] {service}, new InvocationHandler() {

			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {				
				ObjectOutputStream output =null;
				ObjectInputStream input = null;
				try {
				//向服务器发送请求
				Socket socket = new Socket();
				socket.connect(addr);				
			    output =new ObjectOutputStream(socket.getOutputStream()); 
				output.writeUTF(service.getName());              //接口名称
				output.writeUTF(method.getName());               //方法名称
				output.writeObject(method.getParameterTypes());  //方法参数类型
				output.writeObject(args);                        //方法参数
				
				//接收服务器的返回值
			    input = new ObjectInputStream(socket.getInputStream());  				
				return input.readObject();
				}
				catch(Exception e)
				{
					e.printStackTrace();
					return null;
				}
				finally
				{
					try {
						if(output!=null) output.close();
						if(input!=null) input.close();
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}	
				}
			}
			
		});
	}
}

5.服务器端测试

package remote.procedure.call.test;

import remote.procedure.call.server.HelloService;
import remote.procedure.call.server.HelloServiceImpl;
import remote.procedure.call.server.ServerCenter;
import remote.procedure.call.server.ServerCenterImpl;

public class ServerTest {
	public static void main(String[] args)
	{
		 new Thread(new Runnable() {

				@Override
				public void run() {
					ServerCenter server = new ServerCenterImpl(9999);
					//注册服务
					server.register(HelloService.class, HelloServiceImpl.class);
					//启动服务
					server.start();			
				}			
			}).start();
	}	
}

6.客户端测试

package remote.procedure.call.test;

import java.net.InetSocketAddress;

import remote.procedure.call.client.Client;
import remote.procedure.call.server.HelloService;

public class ClientTest {
	public static void main(String[] args) throws ClassNotFoundException
	{
		HelloService service = Client.getRemoteProxyObj(Class.forName("remote.procedure.call.server.HelloService"), new InetSocketAddress("127.0.0.1",9999));
		System.out.print(service.sayHi("April"));
	}
}

猜你喜欢

转载自blog.csdn.net/liyazhen2011/article/details/87859786