При этом в RPC-клиенте произойдет следующее.
1. Он преобразует аргументы вашей функции в байты (иногда это называется
маршаллингом, сериализацией или просто кодированием).
2. Он отправляет закодированные байты удаленной машине.
И вот что происходит на удаленной машине.
1. Она получает закодированные байты запроса.
2. После получения байтов RPC-клиент декодирует их в оригинальные структуры
данных (или аналогичные, если аппаратное и программное обеспечение двух
машин различаются).
3. Затем клиент находит и вызывает локальную функцию с помощью раскодиро-
ванных данных.
4. Далее он кодирует результат работы функции.
5. Наконец, клиент отправляет закодированные байты вызывающей стороне.
После этого машина, запустившая процесс, декодирует полученные байты в воз-
вращенные значения.
RPC — это популярный прием, и люди реализовали его множеством способов.
На стороне сервера вы запускаете серверную программу, создаете механизм для ее
связывания с помощью какого-нибудь способа транспортировки байтов и метода
кодирования/декодирования, определяете функции службы и включаете питание
336
Глава 11. Конкуренция и сети
знака «RPC готов к работе». Клиенты соединяются с сервером и вызывают одну
из его функций с помощью RPC.
Стандартная библиотека содержит только одну реализацию RPC, которая ис-
пользует в качестве формата обмена данными XML, — xmlrpc. Вы определяете
и регистрируете функции на сервере, а клиент вызывает их так, будто они были
импортированы. Сначала рассмотрим файл xmlrpc_server.py:
from xmlrpc.server import SimpleXMLRPCServer
def double(num):
return num * 2
server = SimpleXMLRPCServer(("localhost", 6789))
server.register_function(double, "double")
server.serve_forever()
Функция, которую мы предоставляем на сервере, называется double(). В ка-
честве аргумента она ожидает число, а возвращает это же число, умноженное на
два. Сервер начинает работу на определенных адресе и порте. Нам нужно зареги-
стрировать функцию, чтобы сделать ее доступной клиентам с помощью RPC. На-
конец, можно запустить ее.
Теперь, как вы догадались, рассмотрим файл xmlrpc_client.py:
import xmlrpc.client
proxy = xmlrpc.client.ServerProxy("http://localhost:6789/")
num = 7
result = proxy.double(num)
print("Double %s is %s" % (num, result))
Клиент соединяется с сервером с помощью функции ServerProxy(). Далее он
вызывает функцию proxy.double(). Откуда она появилась? Она была создана дина-
мически с помощью сервера. Механизм RPC волшебным образом прикрепляет имя
функции к вызову удаленного сервера.
Попробуйте сами — запустите сервер и клиент: