@okrug/test-1
v0.0.4-1
Published
Data exchange via the JSON-RPC 2.0 protocol using a message port (postMessage, MessageChannel, MessagePort)
Readme
This is an experimental package; do not use it!
Обмен данными iframe с родительским окном
- Обмен данными с родительских окном производится посредством обмена сообщениями по протоколу JSON-RPC 2.0
- Транспортом для обмена является MessageChannel.
- MessagePort для такого обмена получается путём отправки/обработки запроса
getMessagePortчерезpostMessageродительского окна (window.parent).
Данный клиент реализует базовое взаимодействие и может быть не всегда удобен с учётом использования вашего набора библиотек. Вы можете реализовать свои функции оборачивающие ответ в удобный для вас формат или технологию (promise/rxjs/singals и т.п.). Примеры таких хэлперов для async/await есть ниже в разделе с примерами.
Функции клиента JsonRpcClient
- getMessagePort: получение порта для осуществления обмена данными.
Одновременно с портом можно запросить данные необходимые для первичной инициализации. Сам вызов функции возвращает объект с функциейdispose()для возможности отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функцииcall. - call: вызов одного метода сервера.
Результат обрабатывается в коллбэке. Сам вызов функции возвращает объект содержащий функциюdispose()для возможности отписаться от обработки ответа и вызова коллбэка. В единственный аргумент коллбэка передаются три объекта:response- объект с ответом формата JSON-RPCrequest- оригинальный запрос формата JSON-RPC переданный при вызове (поле jsonrpc: "2.0" заполняется автоматически при отправке запроса, поэтому может отсутствовать в оригинальном запросе если вы его не передавали.)disposable- объект содержащий функциюdispose()для возможности отмены обработки ответа и вызова коллбэка.
Это ровно тот же объект который возращается и самой функциейcall(а такжеbatch/watch/getMessagePort).
Данный объект не очень полезен при выполнении одноразовых запросов, но может быть полезен для записи в него любых необходимых вас данных при использовании функцииwatch
- batch: вызов нескольких методов сервера.
Результат обрабатывается в коллбэке. Сам вызов функции возвращает объект с методомdispose()для возможности отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функцииcall. - watch: запрос периодических уведомлений об изменении указанных данных на сервере.
Возможность наблюдения за изменяемыми значениями не является частью стандарта JSON-RPC, но форматы запросов/ответов соответстуют стандарту.
Сам вызов функции возвращает объект с функциейdispose()для возможности прекратить наблюдение за изменениями и отписаться от вызова коллбэка. Аргумент коллбэка аналогичен аргументу коллбэка функцииcall.
Объектdisposableпередаваемый в аргументе может использоваться для хранения необходимой вам информации между вызовами поскольку ссылка на него не меняется на время подписки. При использовании его в этом качестве будьте осторожны, чтобы не затереть функциюdispose()которую он содержит для отмены обработки ответа. - getUnuqId: генерация уникального строкового идентификтора для запроса.
Используется простейшая логика создания уникального строкового идентификатора. Можно использовать любой другой генератор уникальных строковых или целочисленных значений. - isReady: готовность клиента к обмену данными с сервером (проверяется наличие
MessagePort) - getResponseError: проверка ответа на предмет ошибки.
Результатом будет объект ошибки формата JSON-RPC илиnull. Эта функция не очень полезна при вызове запросов с помощьюcallилиwatchпоскольку результатом ответа всегда будет объект, а результат ответа легко проверить наличием поляerrorв ответе.
В случае cbatchрезультатом ответа может быть как массив так и объект с ошибкой. В этом случае можно проверить ошибку с помощью данной функции. Функция не проверяет наличие вложенных ошибок в массиве ответов.
Примеры использования
Все методы сервера в примера явлюятся вымышленными, у вас будет другой набор реальных метода вашего сервера
Инициализация/запрос порта
const client = createJsonRpcClient();
function init(data) {
console.log("init", data);
}
client.getMessagePort(
{
id: client.getUniqId(),
params: ["host.themeMode", "host.language", "user.id"],
},
({ response }) => {
if (!response.error) {
return init(response.result)
}
console.log("error", response.error)
}
);Вызов одного метода сервера
client.сall(
{
method: "user.id",
id: client.getUniqId(),
},
({ response }) => {
if (response.error) {
console.log("error", response.error);
return;
}
console.log("success", response.result);
},
);Вызов нескольких методов сервера (batch)
client.batch([
{ method: "user.id", id: client.getUniqId() },
{ method: "host.themeMode", id: client.getUniqId() },
])
.then({ response }) => {
const error = client.getResponseError(response)
if (error) {
return console.log("error", error);
}
console.log("success", response.result);
},
);Наблюдение за изменениями значений
При первом событии будет возращён объект содержащий полный набор запрошенных данных. В последующем будут объект будет только объект с данными по которым произошло изменение (формат и логика ответов Вашего сервера может быть иной).
client.watch(
{
method: "changes",
id: client.getUniqId(),
params: ["host.themeMode", "host.language"],
},
({ response, disposable }) => {
if (response.error) {
disposable.dispose();
console.log("error", response.error);
return;
}
disposable.count = 'count' in disposable ? disposable.count++ : 0;
console.log("success", disposable.count, response.result);
},
);Остановка наблюдения за изменениями значений
const disposable = client.watch(
{
method: "changes",
id: client.getUniqId(),
params: ["host.themeMode"],
},
(data) => console.log("data", data),
);
setTimeout(() => {
disposable.dispose();
}, 5000);