简陋的RPC

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

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

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

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

通信

python 复制代码
# common.py
# 这个文件定义了客户端和服务端都知道的"约定"(这就是API接口!)

# 这是我们想要远程调用的方法名
METHOD_ADD = "add"

# 这是我们自己设计的极其简单的"协议"
# 客户端发送的请求格式: method_name,arg1,arg2,...(用逗号分隔的字符串)
# 例如: "add,3,5"
# 服务端返回的响应格式: 直接返回结果,如 "8"

服务端

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

python 复制代码
# server.py
import socket
from common import METHOD_ADD

# 1. 真正实现"远程"方法(服务端本地的函数)
def add(a, b):
    """这就是服务端真正要执行的函数"""
    return a + b

def 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:
            continue
        
        print(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()

客户端

python 复制代码
# client.py
import socket
from common import METHOD_ADD

class SimpleRPCClient:
    def __init__(self, host='localhost', port=9999):
        self.host = host
        self.port = port

    def 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}")
bash 复制代码
✅ RPC 服务端启动在 localhost:9999,等待调用...
📞 来自 ('127.0.0.1', 54437) 的连接
📨 收到原始请求: add,3,5
📤 返回结果: 8
📞 来自 ('127.0.0.1', 54438) 的连接
📨 收到原始请求: add,10,20
📤 返回结果: 30
python 复制代码
=== 方式1: 直接调用call方法 ===
📤 发送请求: add,3,5
📨 收到响应: 8
计算结果: 8

=== 方式2: 调用像本地方法一样的函数 ===
📤 发送请求: add,10,20
📨 收到响应: 30
计算结果: 30

总结

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

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

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

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

相关推荐
wadesir10 小时前
当前位置:首页 > 服务器技术 > 正文Linux网络HSRP协议(实现路由器热备份与高可用性的实用指南)
linux·服务器·网络
泡沫·10 小时前
4.iSCSI 服务器
运维·服务器·数据库
胡八一10 小时前
解决PHP未检测到您服务器环境的sqlite3数据库扩展报错
服务器·数据库·php
不解不惑11 小时前
OpenAI whisper 语音识别服务器搭建
服务器·whisper·语音识别
gaize121311 小时前
适合业务规模较大的场景的服务器测评
服务器
带土111 小时前
4. 两台win11 笔记本局域网内文件传输
网络
悠悠1213811 小时前
告别Zabbix?我用Netdata只花10分钟就搞定了50台服务器的秒级监控(保姆级实战)
运维·服务器·zabbix
天庭鸡腿哥12 小时前
大小只有4K的软件,可让系统瞬间丝滑!
运维·服务器·windows·microsoft·everything
虚伪的空想家12 小时前
华为昇腾Atlas 800 A2物理服务器开启VT-d模式
运维·服务器·ubuntu·kvm·vt-d·直通
xixixi7777712 小时前
“C2隐藏”——命令与控制服务器的隐藏技术
网络·学习·安全·代理·隐藏·合法服务·c2隐藏