• 一个简单RPC框架是怎样炼成的(IV)——实现RPC消息的编解码


    之前我们制定了一个非常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。实际自由度是非常大的。


  • 相关阅读:
    ActiveX控件开发总结(续)
    Guru of the Week 条款04: 类的构造技巧
    tk
    C++中一个空类的大小为什么是1?
    虚继承
    计算机单位
    Guru of the week:#18 迭代指针.
    kingofark关于学习C++和编程的50个观点
    Guru of the Week 条款06:正确使用const
    Guru of the Week 条款07:编译期的依赖性
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6729501.html
Copyright © 2020-2023  润新知