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