gRPC Часть №1 — .NET C# и Google Protobuff. Знакомство.

23 апреля, 2018DEV

Так исторически сложилось, что на текущей моей работе весь стек бекенда состоял изначально из GoLang и .NET. Так начинался наш проект, к  слову, абсолютно для меня экспериментальный — новый виток карьеры (в профессиональном плане). До этого момента я был полностью и целиком desktop-разработчиком под Windows (а ещё до этого десктоп QT и Linux). Я не особо любил писать Web, но судьба иронична 🙂 Так вот, однажды встал вопрос поддержания транспортного уровня между нашими сервисами и в тот момент моему полностью .NET-ориентированному восприятию предстал gRPC.

gRPC — это высопроизводительный протокол для вызова удалённых процедур (собственно, аббревиатура RPCremote procedure call), созданный компанией Google. Задачей данной технологии является взаимодействие вашего кода с каким-либо другим, находящимся в другом адресном пространстве, сервисом. Это инкапсуляция функциональных частей некоторых сервисов, доступных по сети. Кроме непосредственного исполнения бизнес логики, RPC подразумевает автоматическую сериализацию и мапинг ответов в ваши объекты\классы, что делает работу поистине удобной. На транспортном уровне OSI gRPC «стоит» на TCP и на прикладном уровне ходит по HTTP/2. Наиболее близкие и сходные технологии, нативные для .NET — это .NET Remoting и, пришедшая ему на смену, WCF (Windows Communication Foundation).

К слову, разница с WCF у gRPC есть кардинальная, но только на низком уровне. Во-первых, в gRPC не используется SOAP. Во-вторых, это открытый Open Source проект и значит существует возможность связывать мультиязычные системы (Python, PHP, GoLang, C++ и многие другие), а не только языки из .NET стека. Способ сериализации бинарный (против XML/JSON), что даёт ощутимый прирост по скорости. Также сама генерация кодовой базы разная — у gRPC для этого требуются специальные текстовые .proto файлы, содержащие сигнатуры методов (своеобразный Interface), в отличии от WCF — где контрактом общения служит, как правило, скомпилированная единая Class Library DLL-библиотека.

Вот небольшой простенький пример .proto-файла (с именем addressbook.proto), который приводят сами Google:

syntax = "proto3";

package tutorial;

message Person {
  string name = 1;
  int32 id = 2;  // Уникальный числовой идентификатор человека
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

// Адресная книга
message AddressBook {
  repeated Person people = 1;
}

Это очень простой, кроссплатформенный и мультиязычный способ организовать транспортный канал связи между вашими приложениями. Как можно заметить — это строготипизированный подход. Есть возможность организовывать вложенность типов, создание списков (Enum), массивов и многое другое. Каждое поле помечается строчкой с номером (= 1, = 2 etc.) — это маркеры, которые служат для уникальной идентификации этих полей в бинарной кодировке. Поля, помеченные repeated — служает своеобразными динамическими массивами.

Конечно, это только незначительная верхушка айсберга и далека от полного описания прото-файлов. Это очень простой пример. За более глубинными понятиями необходимо засучить рукава и идти в специализированную документацию (хотя, возможно, я опишу всё это отдельным постом).

Итак, теперь у нас есть proto-файл. Нам необходимо сгенерировать по нему кодовую базу. Для этого необходимо использовать специальную утилиту protoc (здесь) — это консольная утилита, которая может взять ваш файл(ы) и создать в вашем проекте все необходимые .cs-файлы. Перед генерацией я бы рекомендовал создать отдельный Class Library проект, чтобы, во-первых, получить переиспользование и, во-вторых, вынести ответственность за транспорт в отдельную зависимость. Генерировать можно так:

protoc -I=$SRC_DIR --csharp_out=$DST_DIR $SRC_DIR/addressbook.proto --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe

На выходе мы получим в нашей указанной папке набор из двух .cs файлов с вашим указанным именем Package.cs и PackageGrpc.cs. Также весь наш код будет определён в namespace, который будет равен строчке package из протофайла. Если вам необходимо использовать какой-либо специализированный namespace, то можно добавить в протофайл следующую строку, явноуказывающую пространство имён:

option csharp_namespace = "Google.Protobuf.Examples.AddressBook";

Итак, будем считать знакомство состоявшимся. Мы немного узнали о gRPC, научились генерировать proto-файлы и добавлять в собственный проект код. В следующих частях мы создадим рабочие проекты клиента и сервера, демонстрирующие какую-либо рабочую и полезную функциональность.

Leave a comment

Ваш адрес email не будет опубликован.

Prev Post Next Post