java分布式调用入门 自定义基于反射 Scoket JKD动态代理 RPC框架
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java分布式调用入门 自定义基于反射 Scoket JKD动态代理 RPC框架,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4395字,纯文字阅读大概需要7分钟。
内容图文
![java分布式调用入门 自定义基于反射 Scoket JKD动态代理 RPC框架](/upload/InfoBanner/zyjiaocheng/829/cded036ff7a54b77b76af13c0183dceb.jpg)
使用工具IDEA, Myeclipse
编写服务端接口 HelloService
服务端实现类
编写服务端的调用类
package whu;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class RpcFramework {
//注册开始方法
public static void export(Object service, Class interfaceClazz, int port) throws Exception {
if (service == null) {
throw new IllegalAccessException("service instance == null");
}
if (port < 0 || port > 65535) {
throw new IllegalAccessException("Invalid port " + port);
}
System.out.println("Export service " + service.getClass().getName() + " on port " + port);
//服务端socket
ServerSocket server = new ServerSocket(port);
//死循环达到不断监听 使用while(true)也一样
for (;;) {
final Socket socket = server.accept();//阻塞等待客户端连接
try {
new Thread(new Runnable() {//多线程
@Override
public void run() {
try {
try {
//获取客户端传来的流对象
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
try {
String interfaceName = input.readUTF();//获取客户端传来需要调用的接口名
String methodName = input.readUTF();//客户端传来需要调用的方法
Class<?>[] parameterTypes = (Class<?>[]) input.readObject();//客户端传来需要调用的方法的参数类型
Object[] arguments = (Object[]) input.readObject();//调用方法的参数
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());//返回客户端的留流对象
try {
//判断客户端需要调用的接口在服务端是否存在
if (!interfaceName.equals(interfaceClazz.getName())) {
throw new IllegalAccessException("Interface wrong, export:" + interfaceClazz
+ " refer:" + interfaceName);
}
Method method = service.getClass().getMethod(methodName, parameterTypes);//通过反射获取服务端的方法
Object result = method.invoke(service, arguments);//执行服务端方法
output.writeObject(result);//返回给客户端
} catch (Throwable t) {
output.writeObject(t);
} finally {
output.close();
}
} finally {
input.close();
}
} finally {
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();//开启线程
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
我这里是直接传入一个对象 你们也可以写一个map用来注册多个对象
服务端启动类
package whu;
public class out {
public static void main(String[] args) throws Exception {
HelloService service = new HelloServiceImpl();
RpcFramework.export(service, HelloService.class, 9000);
}
}
客户端调用类
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.Socket;
public class Rpcfrowd {
/**
* @param args
*/
@SuppressWarnings("unchecked")//屏蔽黄线
public static <T> T refer(final Class<T> interfaceClass, final String host, final int port) throws Exception {
//System.out.println("Get remote service " + interfaceClass.getName() + " from server " + host + ":" + port);
return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] { interfaceClass },
new InvocationHandler() {//jdk 动态代理
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
Socket socket = new Socket(host, port);//建立客户端socket 传入服务端ip 和端口
System.out.println("socket通过");
try {
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());//向服务端写入流对象
try {
output.writeUTF(interfaceClass.getName());//需要调用的接口名
output.writeUTF(method.getName());//需要调用的方法名
output.writeObject(method.getParameterTypes());//需要调用的参数类型
output.writeObject(args);//需要调用的参数
System.out.println("发送成功");
ObjectInputStream input = new ObjectInputStream(socket.getInputStream());//接收服务端的返回信息
try {
Object result = input.readObject();//接收服务端的返回信息
System.out.println("接收成功"+result);
if (result instanceof Throwable) {
throw (Throwable) result;
}
return result;//返回
} finally {
input.close();
}
} finally {
output.close();
}
} finally {
socket.close();
}
}
});
}
}
注意第一个return是返回 生成的代理类对象 第二个是返回调用方法的返回值
客户端启动类
import whu.HelloService;
public class clid {
public static void main(String[] args) throws Exception {
HelloService service = (HelloService)Rpcfrowd.refer(Class.forName("whu.HelloService"), "127.0.0.1", 9000);
String result = service.hello("rod---");
System.out.println(result);
}
}
运行服务端启动类
运行客户端启动类
简单的rpc远程调用就实现了 这里提一下服务端需要接口和实现类 客户端只需要接口就行
内容总结
以上是互联网集市为您收集整理的java分布式调用入门 自定义基于反射 Scoket JKD动态代理 RPC框架全部内容,希望文章能够帮你解决java分布式调用入门 自定义基于反射 Scoket JKD动态代理 RPC框架所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。