rpc通信是如何进行的
发表于:2025-02-12 作者:千家信息网编辑
千家信息网最后更新 2025年02月12日,这篇文章主要介绍了rpc通信是如何进行的的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇rpc通信是如何进行的文章都会有所收获,下面我们一起来看看吧。RPC(Remote
千家信息网最后更新 2025年02月12日rpc通信是如何进行的
这篇文章主要介绍了rpc通信是如何进行的的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇rpc通信是如何进行的文章都会有所收获,下面我们一起来看看吧。
RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
基本概念
RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务
本地过程调用:如果需要将本地student对象的age+1,可以实现一个addAge()方法,将student对象传入,对年龄进行更新之后返回即可,本地方法调用的函数体通过函数指针来指定。
远程过程调用:上述操作的过程中,如果addAge()这个方法在服务端,执行函数的函数体在远程机器上,如何告诉机器需要调用这个方法呢?
今天,我们就通过一个实例代码进行演示,一步步的查看,rpc的通信是如何进行的,有兴趣的朋友可以把代码进行实现,自己debug一下,查看每一步的传参
package com.mashibing.rpc.common;
import java.io.Serializable;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
package com.mashibing.rpc.common;
public interface IUserService {
public User findUserById(Integer id);
}
package com.mashibing.rpc01;
import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;
public class UserServiceImpl implements IUserService {
@Override
public User findUserById(Integer id) {
return new User(id, "Alice");
}
}
package com.mashibing.rpc01;
import com.mashibing.rpc.common.User;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1", 8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(123);
s.getOutputStream().write(baos.toByteArray());
s.getOutputStream().flush();
DataInputStream dis = new DataInputStream(s.getInputStream());
int id = dis.readInt();
String name = dis.readUTF();
User user = new User(id, name);
System.out.println(user);
dos.close();
s.close();
}
}
package com.mashibing.rpc02;
import com.mashibing.rpc.common.User;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
public class Stub {
public User findUserById(Integer id) throws Exception {
Socket s = new Socket("127.0.0.1", 8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(123);
s.getOutputStream().write(baos.toByteArray());
s.getOutputStream().flush();
DataInputStream dis = new DataInputStream(s.getInputStream());
int receivedId = dis.readInt();
String name = dis.readUTF();
User user = new User(id, name);
dos.close();
s.close();
return user;
}
}
package com.mashibing.rpc03;
import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
/**
* 而且Client的调用显得不是很合理(Stub里只有findById的代码),如果有个findByName的新方法,那么就又得重新改进
* 下面这种写法解决了方法增加的问题
*/
public class Stub {
public static IUserService getStub() {
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket s = new Socket("127.0.0.1", 8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(123);
s.getOutputStream().write(baos.toByteArray());
s.getOutputStream().flush();
DataInputStream dis = new DataInputStream(s.getInputStream());
int id = dis.readInt();
String name = dis.readUTF();
User user = new User(id, name);
dos.close();
s.close();
return user;
}
};
Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[] {IUserService.class}, h);
return (IUserService)o;
}
}
package com.mashibing.rpc04;
import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
/**
* 但是这里仅仅实现了findByUserId的方法代理,如果要实现其他方法的代理该怎么做呢?
* 这里就要从协议层做出改进
*
* 服务器端也要做出对应处理
*/
public class Stub {
public static IUserService getStub() {
InvocationHandler h = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket s = new Socket("127.0.0.1", 8888);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
String methodName = method.getName();
Class[] parametersTypes = method.getParameterTypes();
oos.writeUTF(methodName);
oos.writeObject(parametersTypes);
oos.writeObject(args);
oos.flush();
DataInputStream dis = new DataInputStream(s.getInputStream());
int id = dis.readInt();
String name = dis.readUTF();
User user = new User(id, name);
oos.close();
s.close();
return user;
}
};
Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[] {IUserService.class}, h);
return (IUserService)o;
}
}
package com.mashibing.rpc04;
import com.mashibing.rpc.common.IUserService;
import com.mashibing.rpc.common.User;
import java.io.*;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static boolean running = true;
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(8888);
while (running) {
Socket s = ss.accept();
process(s);
s.close();
}
ss.close();
}
private static void process(Socket s) throws Exception {
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
ObjectInputStream oos = new ObjectInputStream(in);
DataOutputStream dos = new DataOutputStream(out);
String methodName = oos.readUTF();
Class[] parameterTypes = (Class[])oos.readObject();
Object[] args = (Object[])oos.readObject();
IUserService service = new UserServiceImpl();
Method method = service.getClass().getMethod(methodName, parameterTypes);
User user = (User)method.invoke(service, args);
dos.writeInt(user.getId());
dos.writeUTF(user.getName());
dos.flush();
}
}
返回值用Object封装,支持任意类型
关于"rpc通信是如何进行的"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"rpc通信是如何进行的"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。
方法
通信
程序
过程
函数
网络
服务
代码
知识
计算机
内容
对象
机器
篇文章
节点
代理
传输
应用
之间
价值
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
mmi表情数据库
wind数据库下载历年数据
搭建kms激活服务器违法吗
石家庄通用服务器
实验中学网络安全宣传材料
网络技术服务协议模板
网络安全管控中心官网
北京直播软件开发平台
网络安全主题言论
服务器怎么申请数字证书
网络安全sp
数据库垂直分表方法
本地数据库怎么还原远程服务
网络安全是靠什么
ftp怎么登录连接服务器
数据库分数怎么找出
数据库文件怎么把有用的导出来
小学生网络安全进课堂
江苏企业软件开发售后服务
如何将winc写入数据库
软件开发工作什么样
Xamarin数据库
神经网络技术分析理论
sql 数据库声明变量
数据库设计考勤系统
OURPLAY下载软件开发
长城网际 网络安全
海南的互联网科技公司排名
小学网络安全应急管理制度
网络安全像