ITKeyword,专注技术干货聚合推荐

注册 | 登录

一个简单RPC框架是如何炼成的(III)——实现带参数的RPC调用

crylearner 分享于 2015-07-19

推荐:一个简单RPC框架是如何炼成的(IV)——实现RPC消息的编解码

之前我们制定了一个很简单的RPC消息 的格式,但是还遗留了两个问题,上一篇解决掉了一个,还留下一个 我们并没有实现相应的encode和decode方法,没有基于可以跨

上一篇,我们制定了一个很简单的RPC消息 的格式,但是还遗留了两个问题

  • 我们并没有实现相应的encode和decode方法,没有基于可以跨设备的字符串传输,而是直接的内存变量传递。
  • 现在的RPC request不支持带参数的请求命令。如add(a, b), 如何在RPC消息中描述参数a,b 。
我先来实现第二个问题,即带参数的RPC调用。

其实,也没什么太大不同。既然是要带参数,那只能扩展原来的Request消息了,加个parameter成员,用于表示参数,具体的格式采用字典方式,{ ’arg1‘, arg1, 'arg2', arg2 ,....}。 这样就可以解决多参数的表示问题。

class Request(object):
    '''
    @RPC请求,包含命令id和请求内容两部分。这个实现,与具体的RPC协议相关。
    @这里是简化起见,采用python自身的字典作为其协议的数据结构
    '''


    def __init__(self):
        '''
        Constructor
        '''
        self.id = 0 #id的作用在于将Request和Response建立绑定关系.在异步调用时就有用
        self.command = None #sayHello
        self.parameter = {}
        
    def __str__(self):
        return ''.join(('id: ', str(self.id),  '    command: ', str(self.command), '    parameter: ', str(self.parameter)))
  

add(a=1, b=2)的RPC 请求就是这个样子了

Request : id = 3, command = 'add', parameter = {'a':1, 'b':2}

对应的,客户端的add方法,我们可以这么写

def add(self, a, b):
        req = Request()
        req.id = 3
        req.command = 'add'
        req.parameter = {'a':a, 'b':b}
        return self.request(req)


那么服务端收到这个RPC请求后,怎么处理得到参数呢?一个传统而稍显笨拙的方式是:

    def add(self, a, b):
        return a + b
    
    def procReqeust__add(self, req):
        parameter = req.parameter
        a = parameter.get('a')
        b = parameter.get('b')
        return self.add(a, b)

这种方式的缺点就是没办法偷懒。(懒懒懒 大笑),每一个RPC调用,都要怎么处理一下,烦死了,没有任何技术含量的纯苦力活,但还考验细心,一不小心搞错a或者b的名字了,呵呵,等着被请喝茶吧。


这时候,大杀器上场,脚本语言就是找个好。总有你想不到的方便。直接上代码

def procReqeust__add(self, req):
        parameter = req.parameter
        return self.add(**parameter)

对上面**parameter不懂的同学自行度娘。这里只是简单解释一下:**parmater的作用同那块笨拙的代码一样,但有一个前提条件,即使add声明时,参数变量名a,b不能变。(c++同学可能晕了,竟然有语音有这样的说法 疑问


至此,使用这种新的方式,我们server的代码就是这个样子的,对没有参数的方法,上面**也是可以放心使用的

def procRequest(self,req):
        rsp = Response()
        rsp.id = req.id   
        if req.command == 'sayHello':
            rsp.result = self.sayHello(**req.parameter)
        elif req.command == 'add':
            rsp.result = self.add(**req.parameter)
        else:
            raise Exception("unknown command")


over,搞定,还挺满意的

推荐:一个高性能RPC框架原理剖析

业务与底层网络通信分离 Server大部分主要分为两层: 网络接收层:负责监听端口,负责收包,编码,解码工作,负责将响应包回传给客户端。 业务处理层:负责接收

上一篇,我们制定了一个很简单的RPC消息 的格式,但是还遗留了两个问题 我们并没有实现相应的encode和decode方法,没有基于可以跨设备的字符串传输,而是直接的内存变量传递。 现在的RPC reques

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。