之前我们制定了一个非常easy的RPC消息 的格式,可是还遗留了两个问题,上一篇解决掉了一个。还留下一个

  • 我们并没有实现对应的encode和decode方法,没有基于能够跨设备的字符串传输,而是直接的内存变量传递。
  • 如今的RPC request不支持带參数的请求命令。

    如add(a, b), 怎样在RPC消息中描写叙述參数a,b 。

以下我们处理掉这个编解码问题。
实际的RPC应用基本都是跨机器连接。所以无法直接传递内存变量,也就是说还须要将消息编码成 诸如字符串一类的能够跨设备传输的内容。

详细的RPC消息的封装协议非常多。常见的是基于xml,json封装的。但假设抽象一下,实际也就是一个编解码,管你编码成什么内容呢。就是不编码也能够。管他黑猫白猫。仅仅要能传过去,就是好猫。

这里我还是简单原则,重点在于晓义嘛。

利用python里的两个运算。

str 和eval。

如果 一个字典msg =  { 'a' : 1, 'b' : 2}.  那么str(msg) =   " {
'a' : 1, 'b' : 2}", 注意变成字符串喽。

        然后eval(" {
'a' : 1, 'b' : 2}")-->msg, 做一个eval运算,又从字符串变成 字典变量了。

       于是编码时。先将RPC消息转换成dict,然后调用str编码成字符串。

         解码时。先调用eval 得到dict对象,然后再转换为详细的RPC消息对象


设计已定,剩下的就仅仅是code filling。
先改动一下原来Request的str方法。返回一个dict的字符串表示。对Response也做类似处理
class Request(object):
def __str__(self):
return str({'id':self.id, 'command':self.command, 'parameter':self.parameter})

然后引入encode方法

    @classmethod
def encode(cls, message):
if isinstance(message, Request):
return str(message)
elif isinstance(message, Response):
return str(message)
elif isinstance(message, Notification):
return str(message)
else:
raise Exception('unknown type when encode')

相同的,引入decode方法,略微复杂一些。基本的麻烦在于怎样区分解码出来的是Response还是Request

我的办法是比較投机的,直接依据字典的内容去推断。有command字段的肯定是request,有result字段的肯定是response
@classmethod
def decode(cls, data):
info = eval(data)
if 'command' in info:
request = Request()
request.id = info.get('id')
request.command = info.get('command')
request.parameter = info.get('parameter', {})
return request
elif 'result' in info:
response = Response()
response.id = info.get('id')
response.result = info.get('result')
return response
elif 'message' in info:
note = Notification()
note.message = info.get('message')
return note
else:
raise Exception('unknown data when decode')

另外,client和server的代码也要稍作调整,那个非常easy,调用一下上面的 方法就能够了。这里不贴了。

over,RPC消息 这一块,我们彻底玩完了。
总结:
  • Request和Resonse的定义能够一直不变。
  • encode 和decode方法,如孙大圣。是能够千变万化的。假设採用xml或者json或者其它的描写叙述,仅仅要自己定义encode和decode方法就可以
  • 从更高的层次看,RPC消息,事实上就是对函数调用的一个描写叙述,所以充其量就是view。既然是view。实际自由度是非常大的。


一个简单RPC框架是怎样炼成的(IV)——实现RPC消息的编解码的更多相关文章

  1. 一个简单RPC框架是怎样炼成的(II)——制定RPC消息

    开局篇我们说了,RPC框架的四个核心内容 RPC数据的传输. RPC消息 协议 RPC服务注冊 RPC消息处理 以下,我们先看一个普通的过程调用 class Client(object): def _ ...

  2. 一个简单RPC框架是怎样炼成的(V)——引入传输层

    开局篇我们说了,RPC框架的四个核心内容 RPC数据的传输. RPC消息 协议 RPC服务注冊 RPC消息处理    接下来处理传输数据.实际应用场景一般都是基于socket.socket代码比較多, ...

  3. 一个简单RPC框架是怎样炼成的(I)——开局篇

    开场白,这是一个关于RPC的相关概念的普及篇系列,主要是通过一步步的调整,提炼出一个相对完整的RPC框架. RPC(Remote Procedure Call Protocol)--远程过程调用协议, ...

  4. 一个简单RPC框架是怎样炼成的(VI)——引入服务注冊机制

    开局篇我们说了.RPC框架的四个核心内容 RPC数据的传输. RPC消息 协议 RPC服务注冊 RPC消息处理 接下来处理RPC服务的注冊机制.所谓注冊机制,就是Server须要声明支持哪些rpc方法 ...

  5. 从零开始实现简单 RPC 框架 7:网络通信之自定义协议(粘包拆包、编解码)

    当 RPC 框架使用 Netty 通信时,实际上是将数据转化成 ByteBuf 的方式进行传输. 那如何转化呢?可不可以把 请求参数 或者 响应结果 直接无脑序列化成 byte 数组发出去? 答:直接 ...

  6. 远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo、SpringClound对比

    远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo.SpringClound对比 远程服务调用RPC框架介绍,RPC简单的来说就是像调用本地服务一样调用远程服务. 分布式RPC需要 ...

  7. 搭建一个简单struts2框架的登陆

    第一步:下载struts2对应的jar包,可以到struts官网下载:http://struts.apache.org/download.cgi#struts252 出于学习的目的,可以把整个完整的压 ...

  8. SCSI miniport 驾驶一个简单的框架

    前段时间,只需用一台新电脑,由于资金有限没有匹配了心仪已久的SSD.我没感觉到飞翔的感觉,总不甘心,仔细想想.我死了相当大的存储,我们可以假设部分内存作为硬盘驱动器把它弄出来.不会比固态硬盘的速度快, ...

  9. vue+vux-ui+axios+mock搭建一个简单vue框架

    1.首先感谢同事 2.之前一直在做angularjs的项目,目前vue火热,所以自己搭建了一个的vue框架,在此作为记录 vue+vux-ui这里就不介绍了,有很多博客都写的很详细了. 下面简单记录下 ...

随机推荐

  1. Java-----jar反编译修改重新打包

    http://blog.csdn.net/hekewangzi/article/details/44676797 一.使用反编译工具JD-GUI(JD-GUI相关操作见Java-----反编译clas ...

  2. Codeforces Round #281 (Div. 2) D. Vasya and Chess 镜面对称 博弈论

    D. Vasya and Chess time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. Codeforces Round #234 (Div. 2) B. Inna and New Matrix of Candies SET的妙用

    B. Inna and New Matrix of Candies time limit per test 1 second memory limit per test 256 megabytes i ...

  4. php 获取所有常量

    有的时候想得到某个完整路径,看看都定义了哪些常量,可以这样做,即把所有的常量都打印出来,然后看看有没有自己想要的,感觉挺方便 官方给的原型: array get_defined_constants ( ...

  5. C++空类产生哪些成员函数 || C++类可以自动生成的6个成员函数

    class Empty {     public:     Empty(); // 缺省构造函数     Empty( const Empty& ); // 拷贝构造函数     ~Empty ...

  6. .NET泛型03,泛型类型的转换,协变和逆变

    协变(Convariant)和逆变(Contravariant)的出现,使数组.委托.泛型类型的隐式转换变得可能. 子类转换成基类,称之为协变:基类转换成子类,称之为逆变..NET4.0以来,支持了泛 ...

  7. Entityframework:启用延时加载的主意事项(只为强化记忆)

    Check List 无参的.高于私有访问级别的构造方法(经常忘记). 非封闭的类(默认的非封闭的). DbContext 配置要开启(默认是开启的). 因为我喜欢将类型设置为封闭的,提供有参数的构造 ...

  8. python接口自动化3-自动发帖(session)

    前言 上一篇模拟登录博客园,但这只是第一步,一般登录后,还会有其它的操作,如发帖,评论等,这时候如何保持会话呢? (敲黑板!!!由于博客园最近登录机制变了,登录全部走cookie登录) 一.sessi ...

  9. git 分支管理策略 与 物理实现 --author by阮一峰 & 小鱼

    -------------------------下面是阮一峰博士的git branch 逻辑结构图示---------------------------------------------- 如果 ...

  10. Android之开源中国客户端源码分析(二)

    1. 加载动画圈实现 <ProgressBar android:id="@+id/main_head_progress" style="@style/loading ...