Обзор
Цитируя спецификацию, JSONRPC «не зависит от транспортного протокола, поскольку описанные концепции можно использовать в одном процессе, через сокеты, через HTTP или во множестве различных сред передачи сообщений».
Чтобы смоделировать эту независимость, библиотека jsonrpc использует объекты класса jsonrpc-connection, представляющие соединение с удалённой конечной точкой JSON (подробную информацию об объектной системе Emacs см. в разделе EIEIO руководства EIEIO). В современной объектно-ориентированной терминологии этот класс является «абстрактным», то есть фактический класс полезного объекта соединения всегда является подклассом jsonrpc-connection. Тем не менее, вокруг класса jsonrpc-connection можно определить два отдельных API:
- API для создания приложений JSONRPC
В этом сценарии новое приложение на основе JSONRPC выбирает конкретный подкласс
jsonrpc-connection, обеспечивающий транспорт для обмена сообщениями JSONRPC между конечными точками.Приложение создаёт объекты этого подкласса с помощью
make-instance. Чтобы установить связь с удалённой конечной точкой, приложение передаёт этот объект таким функциям, какjsonrpc-notify,jsonrpc-requestилиjsonrpc-async-request.Для обработки инициируемых удалённой стороной контактов, которые обычно поступают асинхронно, при создании экземпляра
make-instanceследует инициализировать его аргументами-ключевыми словами EIEIO:request-dispatcherи:notification-dispatcher. Обе эти функции принимают 3 аргумента: объект соединения; символ с именем удалённо вызванного метода JSONRPC; и объект JSONRPCparams.Функция, переданная как
:request-dispatcher, отвечает за обработку запросов удалённой конечной точки, для которых требуется ответ локальной конечной точки (в данном случае — создаваемого вами приложения). Внутри этой функции можно выполнить обычный возврат или нелокальный возврат (выбросить ошибку). При любом из этих способов выхода из диспетчера запросов удалённой конечной точке отправляется ответ на её запрос через транспорт.Обычный возврат определяет успешный ответ, а возвращаемое значение должно быть объектом Lisp, который можно сериализовать в JSON (см. раздел Разбор и генерация значений JSON). Результат передаётся серверу как объект JSONRPC
result. Нелокальный возврат, выполняемый вызовом функцииjsonrpc-error, приводит к отправке серверу ответа об ошибке. Нелокальный возврат, вызванный неожиданной ошибкой любого другого типа, также приводит к отправке ответа. Отладчик не вызывается никогда (если только вы не задалиdebug-on-error; в этом случае может быть вызван отладчик Lisp, см. раздел Вызов отладчика при ошибке).Параметры сопутствующего объекта JSONRPC
errorзаполняются автоматически (в случае неожиданных ошибок) или значениями, переданными вjsonrpc-error(в случае явных вызовов).В исключительном случае явный вызов
jsonrpc-error, задающий:codeравным 32000 и:dataравным любому объекту JSON, означает «ошибки нет» и инициирует обычный ответ удалённой конечной точке, в которомresultприсваивается значение:data. Это полезно, если приложение хочет считать некоторые нелокальные выходы, например выходы по команде пользователя, допустимыми.Библиотеку
jsonrpcможно использовать для создания приложений на основе транспортных протоколов, которые можно назвать «квази-JSONRPC». Они похожи на JSONRPC, но не полностью ему соответствуют, например DAP (протокол адаптера отладки). Эти протоколы также определяют сообщения запросов, ответов и уведомлений, но их формат несколько отличается от JSONRPC. Универсальные функцииjsonrpc-convert-to-endpointиjsonrpc-convert-from-endpointможно настроить для преобразования между внутренним представлением JSONRPC и форматом, принимаемым конечной точкой (см. раздел Универсальные функции). - API для создания транспортов JSONRPC
В этом сценарии от
jsonrpc-connectionсоздаётся подкласс для реализации другой базовой транспортной стратегии (подробную информацию о создании подклассов см. в разделе Наследование.). Затем пользователи интерфейса для создания приложений могут создавать экземпляры этого конкретного класса (с помощью функцииmake-instance) и подключаться к конечным точкам JSONRPC с использованием этой стратегии. Встроенную реализацию транспорта см. в разделе Соединения JSONRPC на основе процессов.Этот API включает обязательные и необязательные части.
Чтобы пользователи могли инициировать контакты JSONRPC (уведомления или запросы) или отвечать на запросы конечных точек, новая реализация транспорта должна предоставить специализацию универсальной функции
jsonrpc-connection-sendдля нового подкласса (см. раздел Универсальные функции). Эта универсальная функция автоматически вызывается такими примитивами, какjsonrpc-requestиjsonrpc-notify. Специализация должна обеспечивать отправку сообщения, описанного в списке аргументов, посредством базового механизма связи (также называемого «каналом»), используемого новым транспортом для взаимодействия с конечными точками. Таким «каналом» может быть сетевой сокет, последовательный интерфейс, HTTP-соединение и т. д.Аналогично, для обработки трёх типов удалённых контактов (запросов, уведомлений и ответов на локальные запросы) реализация транспорта должна обеспечить вызов функции
jsonrpc-connection-receiveиз Elisp после обнаружения в «канале» данных, которые можно использовать для создания сообщения JSONRPC (или квази-JSONRPC).Наконец, в качестве необязательного шага подкласс
jsonrpc-connectionдолжен добавить специализации для универсальных функцийjsonrpc-shutdownиjsonrpc-running-p, если эти концепции применимы к данному транспорту. Специализацияjsonrpc-shutdownдолжна обеспечивать освобождение всех системных ресурсов (например, процессов, таймеров и т. д.), используемых для прослушивания сообщений в канале. Специализацияjsonrpc-running-pдолжна сообщать, остаются ли эти ресурсы активными или уже освобождены (с помощьюjsonrpc-shutdownили иным способом).
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/JSONRPC-Overview.html