Python 원 격 방법 호출 실현 과정 분석

RPCHAndler 와 RPCProxy 의 기본 적 인 사고방식 은 비교적 간단 하 다.클 라 이언 트 가 foo(1,2,z=3)와 같은 원 격 함 수 를 호출 하려 면 프 록 시 클래스 는 함수 이름과 파 라 메 터 를 포함 하 는 원 그룹('foo',(1,2),{'z':3}을 만 듭 니 다.이 원본 그룹 은 pickle 에 의 해 직렬 화 된 후 네트워크 연결 을 통 해 발생 합 니 다.RPCProxy 의 getattr()방법 으로 되 돌아 오 는 dorpc()패키지 닫 기 중 완료.
서버 가 수신 한 후 pickle 반 직렬 화 메 시 지 를 통 해 함수 명 을 찾 아 등 록 했 는 지 확인 한 후 해당 함 수 를 실행 합 니 다.실행 결과(또는 이상)가 pickle 에 의 해 직렬 화 된 후 클 라 이언 트 에 게 되 돌려 보 냅 니 다.인 스 턴 스 는 multiprocessing 에 의존 하여 통신 해 야 합 니 다.그러나 이런 방식 은 다른 어떤 정보 시스템 에 도 적용 된다.예 를 들 어 ZeroMQ 에서 RPC 를 실습 하려 면 연결 대상 을 적합 한 ZeroMQ 의 socket 대상 으로 바 꾸 기만 하면 된다.
서버 쪽 구현

import json
from multiprocessing.connection import Listener
from threading import Thread


class RPCHandler:
  def __init__(self):
    self._functions = {}

  def register_function(self, func):
    self._functions[func.__name__] = func

  def handle_connection(self, connection):
    try:
      while True:
        func_name, args, kwargs = json.loads(connection.recv())
        # Run the RPC and send a response
        try:
          r = self._functions[func_name](*args, **kwargs)
          connection.send(json.dumps(r))
        except Exception as e:
          connection.send(json.dumps(e))
    except EOFError:
      pass


def rpc_server(handler, address, authkey):
  sock = Listener(address, authkey=authkey)
  while True:
    client = sock.accept()
    t = Thread(target=handler.handle_connection, args=(client,))
    t.daemon = True
    t.start()
# Some remote functions
def add(x,y):
  return x+y


if __name__ == '__main__':
  handler = RPCHandler()
  handler.register_function(add)
  # Run the server
  rpc_server(handler, ('127.0.0.1', 17000), authkey=b'peekaboo')
클 라 이언 트 엔 드 구현

import json
from multiprocessing.connection import Client


class RPCProxy:

  def __init__(self, connection):
    self._connection = connection

  def __getattr__(self, name):
    def do_rpc(*args, **kwargs):
      self._connection.send(json.dumps((name, args, kwargs)))
      result = json.loads(self._connection.recv())
      if isinstance(result, Exception):
        raise result
      return result

    return do_rpc
if __name__ == '__main__':
  c = Client(('127.0.0.1', 17000), authkey=b'peekaboo')
  proxy = RPCProxy(c)
  res = proxy.add(2, 3)
  print(res)
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기