代码来源--《分布式服务框架原理与实践》----李林峰--著
三个部分:
1.服务提供者,运行于服务端,负责提供服务接口定义和服务实现类。
2.服务发布者,运行于RPC服务端,负责将本地服务发布成远程服务,提供给其他消费者调用
3.本地服务代理,运行于RPC客户端,通过代理调用远程服务提供者,然后将结果进行封装返回给本地消费者
接口定义
public interface EchoService {
String echo(String ping);
}
实现类:
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String ping) {
return ping != null ? ping + "-->I am ok.I am form Exporter!" : "I am ok.";
}
}
发布者:
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();
}
}
}
}
}
//server启动
public static void main(String[] args) {
try {
RpcExporter.exporter("localhost",8088);
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端:
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(output != null) {
output.close();
}
if(input != null) {
input.close();
}
}
}
});
}
//rpcTest-client启动
public static void main(String[] args) throws Exception{
new Thread(new Runnable() {
@Override
public void run() {
try {
RpcExporter.exporter("localhost",8088);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
RpcImporter<EchoService> impoter = new RpcImporter<EchoService>();
EchoService echo = impoter.importer(EchoServiceImpl.class, new InetSocketAddress("localhost",8088));
System.out.println(echo.echo("Are you ok ? I am from importer!"));
}
}