zoukankan      html  css  js  c++  java
  • 一个简单RPC框架是怎样炼成的(II)——制定RPC消息

    开局篇我们说了,RPC框架的四个核心内容

    1. RPC数据的传输
    2. RPC消息 协议
    3. RPC服务注冊
    4. RPC消息处理
    以下,我们先看一个普通的过程调用
    class Client(object):
        
        def __init__(self):
            self.remote = None
        
        ##
        # 内部是托付给远程remote对象来获取结果。
        def sayHello(self):
            if self.remote: return self.remote.sayHello()
            else : return None
        
    class Server(object):
        
        def __init__(self):
            pass
        
        def sayHello(self):
            return 'Hello World'    
    
    
    if __name__ == '__main__':
        server = Server()
        client = Client()
        client.remote = server
        print(client.sayHello())

    这是一个常见的过程调用的样例,client调用sayHello,实际托付给Server的sayHello方法来实现。但他不是RPC调用。由于起码不是远程的。另外,也没有我们提到的四个核心内容。

    于是我们的任务就是通过一点点的代码改动,为其引入RPC框架。

    第一步,订协议。

    俗话说得好,没有规矩不成方圆。

    还是继续能多简单就多简单。
    RPC请求:Request, 包括一个请求id 和 一个请求命令,如‘sayHello'
    class Request(object):
        '''
        @RPC请求,包括命令id和请求内容两部分。

    这个实现,与详细的RPC协议相关。 @这里是简化起见,採用python自身的字典作为其协议的数据结构 ''' def __init__(self): ''' Constructor ''' self.id = 0 #id的作用在于将Request和Response建立绑定关系.在异步调用时就实用 self.command = None #sayHello def __str__(self): return ''.join(('id: ', str(self.id), ' command: ', str(self.command)))


    相同的,对RPC Response,也定义例如以下
    class Response(object):
        '''
        @RPC回复。 包括答复id和运行结果两部分内容。当中答复id与相应的请求id一致。

    @简单起见。协议的实现使用python自家的字典 ''' def __init__(self): ''' Constructor ''' self.id = 0 self.result = None def __str__(self): return ''.join(('id: ', str(self.id), ' result: ', str(self.result)))


    定义好协议之后,我就对Client稍作改动,将原来直接的接口调用 self.remote.sayHello更改为 send Request (command='sayHello')
        def sayHello(self):
            req = Request() // 构建一个RPC请求消息
            req.id = 1
            req.command = 'sayHello'
            return self.request(req)
      
        def request(self, req):
            rsp = self.remote.procRequest(req) // 将请求消息发送给远程服务端。

    但由于传输层这里还没实现,所以先临时还是直接调用远端接口 return rsp.result


    然后。服务端也要对应改动,须要依据request请求中的command命令,调用详细的方法。并将运行结果封装到Response中,返回给client。
    def procRequest(self,req):
            rsp = Response()
            rsp.id = req.id   
            if req.command == 'sayHello':
                rsp.result = self.sayHello()
            else:
                raise Exception("unknown command")
            
            return rsp

    到这里。RPC框架中的RPC消息已经初具雏形,只是
    • 我们并没有实现对应的encode和decode方法,没有基于能够跨设备的字符串传输,而是直接的内存变量传递。
    • 如今的RPC request不支持带參数的请求命令。如add(a, b), 怎样在RPC消息中描写叙述參数a,b 。
    这些问题我们在后面还会继续展开处理



  • 相关阅读:
    HTML5-拖拽
    POJ1182食物链(并查集)
    欧拉函数之HDU1286找新朋友
    Another kind of Fibonacce(矩阵快速幂,HDU3306)
    我的第一道java_A+B
    bestcoder#33 1002 快速幂取余+模拟乘,组合数学
    快速幂模版
    bestcoder#33 1001 高精度模拟
    poj2446_二分图
    poj3984_bfs+回溯路径
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6952488.html
Copyright © 2011-2022 走看看