Python远程方法调用实现过程解析


Posted in Python onJuly 28, 2020

RPCHandler 和 RPCProxy 的基本思路是很比较简单的。 如果一个客户端想要调用一个远程函数,比如 foo(1, 2, z=3) ,代理类创建一个包含了函数名和参数的元组 (‘foo', (1, 2), {‘z': 3}) 。 这个元组被pickle序列化后通过网络连接发生出去。 这一步在 RPCProxy 的 getattr() 方法返回的 do_rpc() 闭包中完成。

服务器接收后通过pickle反序列化消息,查找函数名看看是否已经注册过,然后执行相应的函数。 执行结果(或异常)被pickle序列化后返回发送给客户端。实例需要依赖 multiprocessing 进行通信。 不过,这种方式可以适用于其他任何消息系统。例如,如果你想在ZeroMQ之上实习RPC, 仅仅只需要将连接对象换成合适的ZeroMQ的socket对象即可。

先实现server端

import json
from multiprocessing.connection import Listener
from threading import Thread


class RPCHandler:
  def __init__(self):
    self._functions = {}

  def register_function(self, func):
    self._functions[func.__name__] = func

  def handle_connection(self, connection):
    try:
      while True:
        func_name, args, kwargs = json.loads(connection.recv())
        # Run the RPC and send a response
        try:
          r = self._functions[func_name](*args, **kwargs)
          connection.send(json.dumps(r))
        except Exception as e:
          connection.send(json.dumps(e))
    except EOFError:
      pass


def rpc_server(handler, address, authkey):
  sock = Listener(address, authkey=authkey)
  while True:
    client = sock.accept()
    t = Thread(target=handler.handle_connection, args=(client,))
    t.daemon = True
    t.start()
# Some remote functions
def add(x,y):
  return x+y


if __name__ == '__main__':
  handler = RPCHandler()
  handler.register_function(add)
  # Run the server
  rpc_server(handler, ('127.0.0.1', 17000), authkey=b'peekaboo')

再实现client端

import json
from multiprocessing.connection import Client


class RPCProxy:

  def __init__(self, connection):
    self._connection = connection

  def __getattr__(self, name):
    def do_rpc(*args, **kwargs):
      self._connection.send(json.dumps((name, args, kwargs)))
      result = json.loads(self._connection.recv())
      if isinstance(result, Exception):
        raise result
      return result

    return do_rpc
if __name__ == '__main__':
  c = Client(('127.0.0.1', 17000), authkey=b'peekaboo')
  proxy = RPCProxy(c)
  res = proxy.add(2, 3)
  print(res)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python登录QQ邮箱发信的实现代码
Feb 10 Python
pyqt4教程之widget使用示例分享
Mar 07 Python
Python中用startswith()函数判断字符串开头的教程
Apr 07 Python
python reduce 函数使用详解
Dec 05 Python
python机器学习之神经网络实现
Oct 13 Python
详解利用python+opencv识别图片中的圆形(霍夫变换)
Jul 01 Python
OpenCV3.0+Python3.6实现特定颜色的物体追踪
Jul 23 Python
python实现DEM数据的阴影生成的方法
Jul 23 Python
Python倒排索引之查找包含某主题或单词的文件
Nov 13 Python
python获取依赖包和安装依赖包教程
Feb 13 Python
Django CSRF认证的几种解决方案
Mar 03 Python
Python中使用subprocess库创建附加进程
May 11 Python
Python 实现一个计时器
Jul 28 #Python
python爬虫要用到的库总结
Jul 28 #Python
Python常用类型转换实现代码实例
Jul 28 #Python
Python 如何创建一个线程池
Jul 28 #Python
matplotlib subplot绘制多个子图的方法示例
Jul 28 #Python
python爬虫用mongodb的理由
Jul 28 #Python
python爬虫数据保存到mongoDB的实例方法
Jul 28 #Python
You might like
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
从康盛产品(discuz)提取出来的模板类
2011/06/28 PHP
分享PHP-pcntl 实现多进程代码
2016/09/30 PHP
IOS 开发之NSDictionary转换成JSON字符串
2017/08/14 PHP
表单切换,用回车键替换Tab健(不支持IE)
2011/07/20 Javascript
使用JS CSS去除IE链接虚线框的三种方法
2013/11/14 Javascript
javascript操作html控件实例(javascript添加html)
2013/12/02 Javascript
js脚本获取webform服务器控件的方法
2014/05/16 Javascript
基于jQuery实现返回顶部实例代码
2016/01/01 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
2016/08/01 Javascript
Vue.js中数组变动的检测详解
2016/10/12 Javascript
jquery文字填写自动高度的实现方法
2016/11/07 Javascript
提高Web性能的前端优化技巧总结
2017/02/27 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
jQuery实现form表单基于ajax无刷新提交方法实例代码
2019/11/04 jQuery
基于Vue+ElementUI的省市区地址选择通用组件
2019/11/20 Javascript
Electron实现应用打包、自动升级过程解析
2020/07/07 Javascript
Python中运行并行任务技巧
2015/02/26 Python
Python中字符串的处理技巧分享
2016/09/17 Python
python3对接mysql数据库实例详解
2019/04/30 Python
Python实现直方图均衡基本原理解析
2019/08/08 Python
Python3爬虫中Ajax的用法
2020/07/10 Python
Python绘图实现台风路径可视化代码实例
2020/10/23 Python
高中生家长寄语大全
2014/04/03 职场文书
小学优秀教育工作者事迹材料
2014/05/09 职场文书
上课说话检讨书
2015/01/27 职场文书
社团个人总结范文
2015/03/05 职场文书
2015中秋节慰问信范文
2015/03/23 职场文书
法院答辩状格式
2015/05/22 职场文书
卢旺达饭店观后感
2015/06/05 职场文书
爱国影片观后感
2015/06/18 职场文书
2016年幼儿园教师政治学习心得体会
2016/01/23 职场文书
评测 | 大屏显示带收音机的高端音箱,JBL TUNE2便携式插卡音箱实测
2021/04/24 无线电
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python
MySQL分布式恢复进阶
2022/07/23 MySQL