首先一点需要明确:一定会发起一个网络请求,一定会有个网络连接(tcp/udp)
- 把远程的函数变成一个http请求 ```python from http.server import HTTPServer, BaseHTTPRequestHandler
host = (‘’, 8003)
class TodoHandler(BaseHTTPRequestHandler): def do_GET(self): from urllib.parse import urlparse, parse_qsl import json parsed_url = urlparse(self.path) qs = dict(parse_qsl(parsed_url.query)) a = int(qs.get(“a”, 0)) b = int(qs.get(“b”, 0)) self.send_response(200) self.send_header(‘Content-type’, “application/json”) self.end_headers() self.wfile.write(json.dumps( { “result”: a + b } ).encode(“utf-8”))
if name == ‘main‘: server = HTTPServer(host, TodoHandler) print(“Starting server, listen at: %s:%s” % host) server.serve_forever()
本地调用
```python
def add(a, b):
return a+b
print(add(1+2))
总结说来,本地程序调用的过程大致可以分为几个步骤和阶段:
- 开发者开发好的程序,并进行编译,编译成机器认可的可执行文件。
- 运行可执行文件,调用对应的功能方法,期间会读取可执行文件中的机器指令,进行入栈,出栈赋值等操作。此时,计算机由可执行程序所在的进程控制。
- 调用结束,所有的内存数据出栈,程序执行结束。计算机继续由操作系统进行控制。
远程过程调用是在两台或者多台不同的物理机器上实现的调用,其间要跨越网络进行调用。因此,我们再想通过前文本地方法调用的形式完成功能调用,就无法实现了,因为编译器无法通过编译的可执行文件来调用远程机器上的程序方法。因此需要采用RPC的方式来实现远端服务器上的程序方法的调用。
RPC技术内部原理是通过两种技术的组合来实现的:本地方法调用 和 网络通信技术。
如果想要做到不用url来确定调用方法和参数怎么办?
改进一下client的代码
import requests
class Client:
def __init__(self, url):
self.url = url
def add(self, a, b):
payload = {
"method": "add",
"params": [a, b],
"jsonrpc": "2.0",
"id": 0,
}
response = requests.post(self.url, json=payload).json()
print(response)
return response["result"]
cli = Client("http://localhost:8001/jsonrpc")
print(cli.add(1,2))
从上面的代码我们关注几点:
- 通信使用了json,所以json中的内容应该如何写就成为了一种协议
- 要想实现远程调用必须要要有网络连接
- 上面通过http连接,可以发现客户端和服务器端之间可以独立,实际上除了通过json以外还可以通过xml作为数据格式
- rpc不应该和http拿来比较
- rpc也不应该和restful拿来比较,我们完全可以把上述代码通过client和server端的封装将rpc编程基于restful来实现
- rpc可以理解为一种调用风格,具体实现可以随意写,至于底层是走tcp协议还是http协议看需求