中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用python實現一個簡單RPC框架

發布時間:2020-10-29 14:23:45 來源:億速云 閱讀:555 作者:Leah 欄目:開發技術

本篇文章給大家分享的是有關使用python實現一個簡單RPC框架,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

客戶端(Client):服務調用方。

  • 客戶端存根(Client Stub):存放服務端地址信息,將客戶端的請求參數數據信息打包成網絡消息,再通過網絡傳輸發送給服務端。
  • 服務端存根(Server Stub):接收客戶端發送過來的請求消息并進行解包,然后再調用本地服務進行處理。
  • 服務端(Server):服務的真正提供者。
  • Network Service:底層傳輸,可以是 TCP 或 HTTP。

實現jsonrpc

在實現前,簡單理一下整體思路。

1、Network Service 直接使用Python Socket相關的API實現 2.傳輸數據使用JSON,在Socket層會被壓成二進制,我們無需關心。

模仿xmlrpc,Client與Server都采用Minix多繼承機制來實現,每個類負責自身的事情,最終暴露出現的只有一個類中有限的方法。

先從Client端開始實現。

# client.py

 

import rpcclient

 

c = rpcclient.RPCClient()

c.connect('127.0.0.1', 5000)

res = c.add(1, 2, c=3)

print(f'res: [{res}]')

實例化rpcclient.RPCClient類,然后調用connect方法鏈接Server端,隨后直接調用Server端的add方法,該方法的效果就是將傳入的數據進行累加并將累加的結果返回,最后將add方法返回的結果打印出了。

RPCClient類繼承于TCPClient類與RPCStub類。

# rpclient.py

class RPCClient(TCPClient, RPCStub):

    pass

其中TCPClient負責通過Socket實現TCP鏈接并將數據請求過去,而RPCStub類主要將Client端調用Server端方法的相關信息打包,然后調用TCPClient類中的方法發送則可,兩個類同樣實現在rpclient.py文件中,代碼如下。

class TCPClient(object):

    def __init__(self):

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

    def connect(self, host, port):

        '''鏈接Server端'''

        self.sock.connect((host, port))

 

    def send(self, data):

        '''將數據發送到Server端'''

        self.sock.send(data)

 

    def recv(self, length):

        '''接受Server端回傳的數據'''

        return self.sock.recv(length)

         

 

class RPCStub(object):

    def __getattr__(self, function):

        def _func(*args, **kwargs):

            d = {'method_name': function, 'method_args': args, 'method_kwargs': kwargs}

            self.send(json.dumps(d).encode('utf-8')) # 發送數據

            data = self.recv(1024) # 接收方法執行后返回的結果

            return data

 

        setattr(self, function, _func)

        return _func

TCPClient類就是常規的Socket API的操作,無需多言,主要看看RPCStub類。

當我們在Client端調用res = c.add(1, 2, c=3)時,會執行RPCStub中的__getattr__方法,該方法會將Client端調用的方法、參數等信息通過TCPServer類的send方法發送,發送數據進行了JSON格式化,方便Server端解碼,隨后便調用recv方法等待Server端相應的數據返回。

因為RPCClient類本身沒有add方法,為了讓用戶做到Client端直接調用Server端方法的形式,先利用__getattr__構建了_func方法,并將其通過setattr方法設置到RPCClient類中,此時該類就有Server端方法對應的映射了。

調用add方法,就調用了對應的_func方法,將數據發送至Server端。

Client端就這樣搞定了,接著來實現Server端,不用緊張,非常簡單。

Server端的使用方式如下。

# server.py

 

import rpcserver

 

def add(a, b, c=10):

    sum = a + b + c

    return sum

 

s = rpcserver.RPCServer()

s.register_function(add) # 注冊方法

s.loop(5000) # 傳入要監聽的端口

實例化rpcserver.RPCServer類,然后通過register_function方法將想被Client端調用的方法傳入,隨后調用loop方法,將要監聽的端口傳入,RPCServer類的實現如下。

# rpcserver.py

 

class RPCServer(TCPServer, JSONRPC, RPCStub):

    def __init__(self):

        TCPServer.__init__(self)

        JSONRPC.__init__(self)

        RPCStub.__init__(self)

 

    def loop(self, port):

        # 循環監聽 5000 端口

        self.bind_listen(port)

        print('Server listen 5000 ...')

        while True:

            self.accept_receive_close()

 

    def on_msg(self, data):

        return self.call_method(data)

RPCServer繼承自TCPServer、JSONRPC、RPCStub,這些類同樣實現在rpcserver.py文件中并且給出了詳細的注釋,所以就詳細解釋了。

class TCPServer(object):

    def __init__(self):

        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

    def bind_listen(self, port):

        self.sock.bind(('0.0.0.0', port))

        self.sock.listen(5)

 

    def accept_receive_close(self):

        '''獲取Client端信息'''

        (client_socket, address) = self.sock.accept()

        msg = client_socket.recv(1024)

        data = self.on_msg(msg)

        client_socket.sendall(data) # 回傳

        client_socket.close()

 

 

class JSONRPC(object):

    def __init__(self):

        self.data = None

 

    def from_data(self, data):

        '''解析數據'''

        self.data = json.loads(data.decode('utf-8'))

 

    def call_method(self, data):

        '''解析數據,調用對應的方法變將該方法執行結果返回'''

        self.from_data(data)

        method_name = self.data['method_name']

        method_args = self.data['method_args']

        method_kwargs = self.data['method_kwargs']

        res = self.funs[method_name](*method_args, **method_kwargs)

        data = {"res": res}

        return json.dumps(data).encode('utf-8')

 

 

class RPCStub(object):

    def __init__(self):

        self.funs = {}

 

    def register_function(self, function, name=None):

        '''Server端方法注冊,Client端只可調用被注冊的方法'''

        if name is None:

            name = function.__name__

        self.funs[name] = function

至此,Client端和Server端都寫好了。

測試:

使用python實現一個簡單RPC框架

以上就是使用python實現一個簡單RPC框架,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

施秉县| 白银市| 保德县| 巴中市| 靖宇县| 黔西| 闽清县| 湘潭县| 辉县市| 涞源县| 贵南县| 漳平市| 五家渠市| 宁强县| 英超| 友谊县| 蒙山县| 仁布县| 武清区| 赞皇县| 北安市| 含山县| 旌德县| 灌云县| 新干县| 东阳市| 舞阳县| 盖州市| 离岛区| 保山市| 益阳市| 海门市| 浪卡子县| 宜阳县| 谷城县| 二连浩特市| 南召县| 巴林左旗| 昭觉县| 忻州市| 荆州市|