当前位置: 首页 > news >正文

简陋的RPC

使用Socket实现客户端,服务端,通信

1.客户端。调用"远程"的add(a,b)方法,就像调用本地方法一样。

2. 服务端。在另一个进程里,真正实现这个add方法。

3. 通信:设计一个简陋的协议,调用TCP Socket传输调用信息和结果】

通信

# common.py
# 这个文件定义了客户端和服务端都知道的“约定”(这就是API接口!)# 这是我们想要远程调用的方法名
METHOD_ADD = "add"# 这是我们自己设计的极其简单的“协议”
# 客户端发送的请求格式: method_name,arg1,arg2,...(用逗号分隔的字符串)
# 例如: "add,3,5"
# 服务端返回的响应格式: 直接返回结果,如 "8"

服务端

服务端监听端口,收到请求后,解析协议,调用本地方法,返回结果。服务端监听端口,收到请求后,解析协议,调用本地方法,返回结果。

# server.py
import socket
from common import METHOD_ADD# 1. 真正实现“远程”方法(服务端本地的函数)
def add(a, b):"""这就是服务端真正要执行的函数"""return a + bdef run_server(host='localhost', port=9999):# 2. 创建一个TCP Socket(搞个座机)server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)server_socket.bind((host, port)) # 告诉座机电话号码server_socket.listen(5) # 开始接听,最多5个排队print(f"✅ RPC 服务端启动在 {host}:{port},等待调用...")# 3. 死循环,一直处理客户端打来的电话while True:client_socket, addr = server_socket.accept() # 接电话print(f"📞 来自 {addr} 的连接")# 4. 读取客户端发来的请求(对方在电话里说的话)request_data = client_socket.recv(1024).decode('utf-8').strip()if not request_data:continueprint(f"📨 收到原始请求: {request_data}")# 5. 【解析协议】按照我们的约定,解析对方的话parts = request_data.split(',')method_name = parts[0]args = parts[1:]result = None# 6. 根据方法名,调用本地对应的函数if method_name == METHOD_ADD:if len(args) == 2:a, b = int(args[0]), int(args[1])result = add(a, b) # 真正调用本地函数!else:result = "Error: add方法需要2个参数"else:result = f"Error: 未知方法 {method_name}"# 7. 把函数执行结果返回给客户端print(f"📤 返回结果: {result}")client_socket.sendall(f"{result}".encode('utf-8'))# 8. 挂电话client_socket.close()if __name__ == '__main__':run_server()

客户端

# client.py
import socket
from common import METHOD_ADDclass SimpleRPCClient:def __init__(self, host='localhost', port=9999):self.host = hostself.port = portdef call(self, method_name, *args):"""真正的远程调用核心方法"""# 1. 建立到服务端的TCP连接(拨号)sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((self.host, self.port))# 2. 【封装协议】按照我们的约定,组装请求消息# 格式: "method_name,arg1,arg2,..."request_data = f"{method_name},{','.join(str(arg) for arg in args)}"# 3. 发送请求(对着电话说话)print(f"📤 发送请求: {request_data}")sock.sendall(request_data.encode('utf-8'))# 4. 等待并接收服务端的响应(听对方回复)response_data = sock.recv(1024).decode('utf-8')print(f"📨 收到响应: {response_data}")# 5. 关闭连接(挂电话)sock.close()# 6. 返回结果return response_data# 提供一个“本地方法”一样的假象
def add(a, b):"""客户端版本的add方法,它内部是远程调用"""client = SimpleRPCClient()result = client.call(METHOD_ADD, a, b)return int(result) # 将字符串响应转换为整数if __name__ == '__main__':# 使用方式1:直接使用底层call方法print("=== 方式1: 直接调用call方法 ===")client = SimpleRPCClient()result = client.call(METHOD_ADD, 3, 5)print(f"计算结果: {result}\n")# 使用方式2:调用包装好的函数,像本地方法一样!print("=== 方式2: 调用像本地方法一样的函数 ===")sum_result = add(10, 20)print(f"计算结果: {sum_result}")
✅ RPC 服务端启动在 localhost:9999,等待调用...
📞 来自 ('127.0.0.1', 54437) 的连接
📨 收到原始请求: add,3,5
📤 返回结果: 8
📞 来自 ('127.0.0.1', 54438) 的连接
📨 收到原始请求: add,10,20
📤 返回结果: 30
=== 方式1: 直接调用call方法 ===
📤 发送请求: add,3,5
📨 收到响应: 8
计算结果: 8=== 方式2: 调用像本地方法一样的函数 ===
📤 发送请求: add,10,20
📨 收到响应: 30
计算结果: 30

总结

1. RPC的本质:客户端代理+网络传输+服务端分发。客户端调用的add函数根本不在本地,而是通过网络告诉服务端“帮我执行一个add函数”,然后把结果给我

2.协议的作用:客户端和服务端必须有一个共同的约定(Protocol),才知道怎么打包和解析数据。这里用的是简单的逗号分隔字符串。现实中用的是Protobuf,Thrift等更高效的协议。

3. TCP的作用:提供了可靠的、双向的字节流通道。这里的“协议”字符串就是通过这个通道传输的

4. 框架的作用:Dubbo、gRPC就是把这个过程抽象化、优化。它们帮自动生成代理、管理连接池、处理序列化、负责服务器发现。让你用一行@Reference就搞定一切。

http://www.dtcms.com/a/362717.html

相关文章:

  • 从代码到组件:C语言动态库(DLL)封装与使用终极指南
  • NV115NV119美光固态闪存NV129NV112
  • 加速交通云建设,移动云为我国交通强国目标提供有力支撑
  • AES-GCM和(AES-CBC+SHA2-25-HAMC组合,并且发方通过每次内容,更新iv,填序使用递增数字)算法比较
  • 系统科学核心概念辨析及其在人工智能领域的应用研究:一个整合性分析框架
  • 分布式光纤传感选型 3 问:你的场景该选 DTS、DAS 还是 BOTDA?
  • 解锁WebRTC在数字人领域的无限潜能
  • 面试问题:c++的内存管理方式,delete的使用,vector的resize和reverse,容量拓展
  • 大数据量模块设置渲染性能优化
  • 白电三巨头 2025 年战局:美的领跑破局,海尔稳健筑垒,格力承压求变
  • Spring 中 Hikari 与 Druid 的详细介绍、对比及同类组件分析
  • go-mapus最简单的离线瓦片地图协作
  • 【Linux系统】万字解析,进程间的信号
  • 并发编程——13 线程池ThreadPoolExecutor实战及其原理分析
  • md5sum -c用法详解
  • 【Vue2 ✨】Vue2 入门之旅(八):过渡与动画
  • 基础文本处理工具与文本三剑客其二sed awk
  • unity 中的 gradle building 加速(可能无用,导致包体异常)
  • 【C++详解】C++11(三) 可变参数模板、包扩展、empalce系列接⼝、新的类功能
  • MyBatis:让 SQL 与代码和谐共处的持久层框架
  • React学习教程,从入门到精通, React 入门指南:React JSX 语法知识点详解及案例代码(8)
  • React 学习笔记4 Diffing/脚手架
  • go命令行工具:如何在现有的工程里加入使用cobra
  • 01 - 网页和web标准
  • AI文档产品与传统OCR软件的根本区别是什么?
  • Java集合源码解析之LinkedList
  • HTTPS如何保证数据传输过程中的安全性?
  • mapbox高阶,结合threejs(threebox)添加管道,实现管道流动效果
  • 红楼梦 HTML 分析 - 娇杏为何侥幸
  • ES6和CommonJS模块区别