1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Bwar-Nebula

Клонировать/Скачать
protocol.md 13 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 22:21 646366b

Коммуникационный протокол Nebula

Nebula разделяет сетевые сообщения на запросы (request) и ответы (response). На самом деле, все типы сетевых сообщений можно отнести к запросам или ответам.

Коммуникационный протокол Nebula

Nebula поддерживает такие протоколы связи, как protobuf, http и websocket. Основанный на protobuf3, разработанный по индивидуальному проекту, коммуникационный протокол Nebula является основным протоколом связи Nebula. Он используется для обмена данными между распределёнными сервисными узлами Nebula, а также для взаимодействия с внешними клиентами распределённых сервисов. Протоколы http, websocket и другие, поддерживаемые Nebula, после декодирования в слое подключения Nebula преобразуются в протокол связи Nebula и используются для обмена данными между узлами. В качестве слоя бизнес-логики данные структуры могут быть непосредственно прочитаны и записаны. Ниже приведено определение протокола Nebula:

syntax = "proto3";

/**
 * @brief 消息头
 * @note MsgHead всегда имеет длину 15 байт. Если длина MsgHead не равна 15 байтам, отправка сообщения завершится ошибкой.
 * В версии proto2 длина MsgHead всегда равна 15 байтам. В этой версии cmd, seq и len являются обязательными полями.
* В версии proto3 длина MsgHead должна быть равна 15 байтам. При этом cmd, seq и len должны быть ненулевыми, иначе невозможно будет правильно выполнить кодирование и декодирование отправки и получения.
 */
message MsgHead {
    fixed32 cmd = 1; // команда (1 байт, старший бит представляет алгоритм сжатия и шифрования)
    fixed32 seq = 2; // порядковый номер
    sfixed32 len = 3; // длина сообщения
}

/**
 * @brief Тело сообщения
 * @note Тело сообщения — это data. Вся бизнес-логика содержится в data. req_target используется на стороне сервера для маршрутизации и должен быть заполнен в запросе. rsp_result должен быть заполнен в ответе.
*/
message MsgBody {
    oneof msg_type {
        Request req_target = 1; // цель запроса (заполняется в запросе)
        Response rsp_result = 2; // результат ответа (заполняется в ответе)
    }
    bytes data = 3; // тело сообщения
    bytes add_on = 4; // данные, добавленные на стороне сервера в запрос (клиент не обращает внимания)
    string trace_id = 5; // для трассировки журнала

    message Request {
        uint32 route_id = 1; // идентификатор маршрута
        string route = 2; // идентификатор маршрута (используется, когда route_id не может выразить маршрут)
    }

    message Response {
        int32 code = 1; // код ошибки
        bytes msg = 2; // сообщение об ошибке
    }
}

Протокол Nebula состоит из MsgHead и MsgBody. Это широко используемый протокол TLV. MsgHead имеет фиксированную длину 15 байт. Команда cmd указывает функцию обработчика сообщений, и в Nebula принято, что если cmd является нечётным числом, то сообщение является запросом, а если оно является чётным числом, то сообщением является ответ. Таким образом, можно избежать поля типа сообщения request/response. Длина команды составляет 32 бита (4 байта), но только младшие 2 байта используются в качестве функции команды, а старшие 2 байта представляют алгоритм сжатия, шифрования и версию. Это делается для того, чтобы максимально сэкономить пропускную способность, поскольку 2-байтовая команда уже может представлять 32 266 функций (65 535/2, 0 не может использоваться в качестве команды, и исключая зарезервированные команды запроса Nebula 500), которых достаточно для использования в бизнесе.

Поле data в MsgBody хранит тело сообщения, и любые пользовательские данные могут быть записаны в двоичном потоке данных в data.

msg_type используется для определения того, является ли сообщение запросом или ответом. Если это запрос, вы можете выбрать заполнение route_id или route в Request. Если они заполнены, фреймворк может автоматически пересылать их без необходимости анализа прикладного протокола (и не может анализировать), а приложению не нужно разбирать содержимое data для пересылки в соответствии с настраиваемой логикой. Если это ответ, он определяет унифицированный стандарт ошибок и предоставляет удобство для обработки ошибок, не связанных с бизнесом.

add_on — это данные, прикреплённые к длительному соединению. Фреймворк не анализирует их, но добавляет их при каждой пересылке сообщения. Они предоставляют чрезвычайно удобные и мощные функции для приложений. Например, при входе пользователя в систему IM клиент отправляет только идентификатор пользователя и пароль на сервер. После успешной проверки входа сервер использует метод SetClientData() для добавления информации о псевдониме и аватаре пользователя в соответствующее длительное соединение Channel этого пользователя. Затем все запросы, поступающие через это соединение, будут автоматически заполнять поле add_on фреймворком, а другая логика сервера получает только данные бизнес-логики (например, сообщения чата) из data, но может получить информацию об отправителе из поля add_on. Дизайн add_on упрощает логику разработки приложений и снижает объём данных, передаваемых между клиентом и сервером.

trace_id используется для распределённой трассировки журналов. Распределённая служба ошибок очень сложна. Nebula предоставляет функцию распределённой службы трассировки, которая позволяет фреймворку помечать все журналы с одним и тем же trace_id для отправки на указанный сервер журналов без дополнительной работы со стороны разработчиков приложений (обычная запись LOG4_INFO без дополнительной работы). Например, если сообщение, отправленное пользователем IM, не удаётся отправить, trace_id будет добавлен при отправке сообщения на сторону сервера. Этот идентификатор будет передаваться на каждом этапе пути обработки и ошибок. Вы можете найти путь обработки и ошибок из сообщения.

Реализация кодирования и декодирования MsgHead и MsgBody см. в https://github.com/Bwar/Nebula/blob/master/src/codec/CodecProto.cpp в рамках Nebula.

Http-протокол связи

Http-протокол является лучшим выбором для предоставления внешних услуг. Будучи универсальным сетевым фреймворком, http-протокол, естественно, является наиболее важным протоколом для Nebula для предоставления внешних служб. Nebula превращает http-протокол в protobuf и анализирует текстовый протокол http для преобразования в HttpMsg, который обрабатывается внутри службы. Разработчики приложений заполняют HttpMsg, а слой подключения преобразует ответный HttpMsg обратно в текстовый протокол http и отправляет его запрашивающей стороне. Независимо от того, сколько раз происходит внутренняя передача, существует только один этап декодирования текстового протокола http и один этап кодирования текстового протокола http. Ниже приводится определение protobuf для http-протокола:

syntax = "proto3";
message HttpMsg {
    int32 type = 1; // тип http_parser_type (запрос или ответ)
    int32 http_major = 2; // основная версия http
    int32 http_minor = 3; // дополнительная версия http
    int32 content_length = 4; // длина содержимого
    int32 method = 5; // метод запроса
    int32 status_code = 6; // статус ответа
    int32 encoding = 7; // кодировка передачи (используется только при кодировании, когда Transfer-Encoding: chunked, используется для обозначения номера чанка, 0 означает первый чанк, увеличивается последовательно)
    string url = 8; // адрес
}
``` map<string, string> headers = 9;  // http头域
bytes body = 10; // 消息体(当 Transfer-Encoding: chunked 时,只存储一个 chunk)
map<string, string> params = 11; // GET方法参数,POST方法表单提交的参数
Upgrade upgrade = 12; // 升级协议
float keep_alive = 13; // keep alive time
string path = 14; // Http Decode时从 url 中解析出来,不需要人为填充(encode时不需要填)
bool is_decoding = 15; // 是否正在解码(true 正在解码, false 未解码或已完成解码)

message Upgrade {
    bool is_upgrade = 1;
    string protocol = 2;
}

&emsp;&emsp;HttpMsg的编解码实现见 Nebula 框架的 [https://github.com/Bwar/Nebula/blob/master/src/codec/CodecHttp.cpp](https://github.com/Bwar/Nebula/blob/master/src/codec/CodecHttp.cpp)。

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/Bwar-Nebula.git
git@api.gitlife.ru:oschina-mirror/Bwar-Nebula.git
oschina-mirror
Bwar-Nebula
Bwar-Nebula
master