一個簡單RPC框架是如何煉成的(III)——實現帶參數的RPC調用

上一篇,我們制定了一個很簡單的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,搞定,還挺滿意的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章