И межплатформенный обмен данными между клиентом Node.js и службой Windows C #.

Microsoft Windows Communication Foundation (WCF) всегда был моей платформой для общения в Windows.

Мне нравится иметь возможность изменять протокол и формат через конфигурацию.

  • Вам нужна широчайшая совместимость с другими системами и языками? Вы используете WsHttpBinding.
  • Вам нужна максимальная скорость между двумя процессами на одной машине? Вы используете NetNamedPipeBinding.

Но, к моему сожалению, Microsoft не перенесла WCF на платформу .Net Core. Платформа .Net Core является кроссплатформенной, и Microsoft тесно связала WCF с операционной системой Windows. Тесная связь затрудняет им миграцию WCF.

В этой статье я опишу, как и почему я перешел с WCF на gRPC. Поскольку gRPC является кроссплатформенным, я покажу пример, который обменивается данными между службой .Net Core и клиентом Node.js.

Я использую Visual Studio 2019 для создания службы gRPC ASP.Net Core и кода Visual Studio для клиента Node.js.

В конце статьи я перечислю альтернативы gRPC.

Зачем вам мигрировать?

Причина перехода от WCF проста. Microsoft рекомендует использовать .Net Core для разработки всех новых приложений. Поскольку Microsoft .Net Core не поддерживает WCF, вам необходимо выполнить миграцию.

Вы можете вообще отказаться от миграции и остаться на платформе Microsoft .Net. Возможный вариант, но вы не окажете себе услуги. Будущие инвестиции Microsoft в .NET будут в .NET Core.

Microsoft рекомендует gRPC в качестве альтернативы WCF для .Net Core.

Есть ли альтернативы? Да, вы можете использовать HTTP API или веб-сокеты. Но имейте в виду, что HTTP API менее производительны, а веб-сокеты требуют ручной работы для сериализации сообщений.

В чем разница между WCF и gRPC?

Наиболее существенные различия между WCF и gRPC заключаются в следующих областях:

  • Определение интерфейса
  • Протокол и формат
  • Обработка ошибок
  • Безопасность

Определение интерфейса

С помощью WCF вы описываете интерфейс своей службы через интерфейс C #. Сервер WCF генерирует WSDL посредством отражения во время выполнения. Генераторы клиентов используют WSDL для создания клиентов для службы.

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

Буферы протокола - это настраиваемый язык. Это делает gRPC независимым от платформы и языка. Каждая платформа и язык могут разрабатывать генераторы для создания клиентов и заглушек сервисов.

Протокол и формат

С WCF вы можете использовать конфигурацию для выбора различных протоколов и форматов связи. Например, HTTP, TCP, MSMQ или именованные каналы. Протокол и формат указываются с помощью привязок - например, привязки NetTcp.

gRPC использует HTTP / 2 для сетевого протокола и формата двоичного сообщения. gRPC предлагает ту же скорость и эффективность, что и привязка WCF NetTcp. В некоторых случаях даже более высокая скорость.

Обработка ошибок

С WCF вы можете использовать FaultException<TDetail> для предоставления информации об ошибках, соответствующей стандарту SOAP Fault.

gRPC не имеет расширенной обработки ошибок. gRPC использует коды состояния и метаданные. В следующей таблице показаны наиболее часто используемые коды состояния.

  • GRPC_STATUS_UNIMPLEMENTED Метод не реализован
  • GRPC_STATUS_UNAVAILABLE У службы есть общая проблема, и она недоступна.
  • GRPC_STATUS_INTERNAL У сервиса проблема с кодированием / декодированием сообщений.
  • GRPC_STATUS_UNAUTHENTICATED Ошибка аутентификации на сервере
  • GRPC_STATUS_PERMISSION_DENIED У клиента нет полномочий на выполнение запрошенного действия.
  • GRPC_STATUS_CANCELLED Клиент отменил звонок

Безопасность

С WCF у вас есть много вариантов безопасности. Вы хотите использовать шифрование на уровне сообщений или шифрование значений? Какую аутентификацию вы хотите? Интеграция с Active Directory, Kerberos, LDAP и т. Д.

gRPC использует HTTP / 2. Хотя можно использовать незашифрованные данные через HTTP / 2, все основные браузеры поддерживают только HTTP / 2 через TLS. Таким образом, HTTP / 2 всегда будет использовать шифрование с использованием TLS. Так будет gRPC.

Вы можете использовать сертификаты клиента и сервера для аутентификации. Если вы хотите использовать авторизацию на уровне звонка, вы можете использовать токены, например, Jason Web Tokens (JWT).

Теперь давайте разберемся, что такое gRPC.

Что такое gRPC?

Вызов удаленных процедур общего назначения (gRPC) - это коммуникационная среда с открытым исходным кодом, изначально разработанная Google. Нет, g не означает Google. Он использует буферы протокола Google для описания интерфейса связи.

Буферы протокола - это кроссплатформенный механизм сериализации данных.

Вы должны описать интерфейс связи в файле .proto. Файл .proto содержит определения всех типов сообщений. gRPC включает генераторы для многих разных языков, например:

  • Джава
  • Python
  • Цель-C
  • C++
  • Дротик
  • Go
  • Рубин
  • C#

Пример gRPC

Давайте посмотрим на пример. Файл .proto ниже определяет службу под названием Graph DefinitionService. Эта служба содержит два метода. Один для получения одного определения графа, а другой - для чтения всех определений графов.

Первая строка определяет syntax прототипа, который вы хотите использовать. Доступны две версии: «proto2» и «proto3». Я рекомендую использовать версию 3, потому что она поддерживает больше языков.

Третья строка содержит инструкцию option. Эти утверждения относятся к определенному языку. В данном случае для C #, поэтому при использовании генератора java параметры charp_ игнорируются.

package definition в пятой строке имеет важное значение. Он определяет название службы.

Методы обслуживания

Оператор service в строке седьмой запускает методы, которые будут доступны в вашем сервисе. Каждый метод начинается с rpc. Вы можете сравнить это с OperationContract в службе WCF.

Каждый метод службы gRPC принимает сообщение и возвращает сообщение. Невозможно иметь единственный целочисленный аргумент или вернуть пустоту.

Определение сообщения

Определение сообщения начинается с ключевого слова message. Например, в строке 12 определено сообщение GetRequest. Это сообщение содержит одно поле с именем graphDefinitionId типа int32.

Protocol Buffer поддерживает несколько собственных типов данных, таких как int32, double и string. Не существует собственного GUID для типа данных UUID, который я часто использую в качестве поля Id. Лучший способ решить эту проблему - использовать вместо этого строку.

После каждого поля в определении сообщения стоит уникальный номер. Этот номер идентифицирует поле в двоичном сообщении. Поэтому вам следует присвоить номер и никогда не менять его, если ваш тип сообщения уже используется.

Даже если вам больше не нужно поле, вы можете удалить его, но не следует повторно использовать номер поля. Просто оставьте пробелы.

Создание службы gRPC

Хотя можно создать службу gRPC с помощью Visual Studio Code, я буду использовать Visual Studio 2019. Visual Studio 2019 значительно упрощает этот процесс.

Visual Studio содержит шаблон проекта для создания службы gRPC. Этот шаблон создает проект ASP.NET Core 3.1. Он содержит службу и пример .proto файла.

Visual Studio переводит файл .proto в частичные классы C # с виртуальными методами во время сборки. Вы можете унаследовать от этих частичных классов и реализовать методы службы путем переопределения. См. Ниже пример реализации GraphDefinitionService.

Полное решение доступно на GitHub.

Создание клиента gRPC .Net Core

Сначала я создам клиент gRPC с помощью Visual Studio 2019. Я использую консольный проект .Net Core.

Затем установите следующие пакеты Nuget с помощью консоли диспетчера пакетов в Visual Studio.

  • Инсталляционный пакет Grpc.Net.Client
  • Установочный пакет Google.Protobuf
  • Установочный пакет Grpc.Tools

Скопируйте или свяжите GraphDefinitionService.proto с клиентской программой. Выберите файл proto и установите правильные свойства компиляции. Убедитесь, что для свойства gRPC Sub Classes указано значение Client only.

Следующая программа подключается к службе gRPC GraphDefinitionService и вызывает метод GetAsync method.

Создание клиента gRPC на Node.js

Чтобы продемонстрировать кроссплатформенные возможности, я также реализовал gRPC-клиент Node.js.

Клиенту Node.js нужны следующие два пакета NPM.

npm install grpc @grpc/proto-loader

Ему также необходим доступ к файлу graphdefinitionservice.proto, чтобы иметь возможность генерировать классы-заглушки.

В отличие от C #, библиотеки gRPC Node.js генерируют коммуникационную заглушку во время выполнения. В строке 16 загружается прото-файл, и Node.js генерирует заглушку. Клиент создает фактическое соединение с сервисом в строке 18.

В строке 23 клиент совершает фактический вызов службы. Полный исходный код доступен на Github.

Переход с WCF на gRPC

gRPC может быть отличной альтернативой WCF. Но поскольку вы, вероятно, вложили много времени и энергии в свои службы WCF. Возможно, вас заинтересует возможность автоматической миграции ваших служб WCF.

Visual ReCode - это коммерческий плагин Visual Studio, который помогает перенести ваши службы WCF на gRPC. Visual ReCode сканирует проекты в вашем решении и ищет все интерфейсы WCF, просматривая атрибут [OperationContract].

Затем он позволяет вам выбрать интерфейс WCF, который вы хотите перенести. После выбора он создает для каждого интерфейса:

  • Прототип файла, основанный на оригинальном интерфейсе WCF.
  • Служба gRPC, реализующая прототип файла и вызывающая исходный код.
  • Клиент gRPC, который может вызывать все методы службы gRPC.

Тем не менее, вам придется поработать вручную. Но если вам нужно перенести много служб WCF, я бы порекомендовал проверить Visual ReCode. Доступна пробная версия.

Заключение и альтернативы

В этой статье мы увидели, что Microsoft не поддерживает WCF в .Net Core. Вы можете использовать gRPC, который является хорошей альтернативой для создания высокоскоростных сервисов. Другие варианты - это базовые HTTP API и веб-сокеты.

Мы реализовали службу gRPC ASP .NET Core и клиент Node.js. Исходный код доступен на Github.

Если вы хотите перенести свои службы WCF на gRPC, вы можете сделать это вручную или с помощью инструмента. Такой инструмент, как Visual ReCore, может помочь, особенно если у вас много служб WCF.

Альтернативой WCF, о которой я раньше не упоминал, является Core WCF. Core WCF - это порт Windows Communication Framework (WCF) с открытым исходным кодом на .NET Core. В настоящее время он не готов к производству. Но в будущем это может быть альтернативой, которая может запускать службы WCF в .Net Core.

Прежде чем вы начнете преобразовывать свои службы WCF в gRPC, я хочу поделиться двумя вещами. На момент написания этой статьи было невозможно запустить gRPC в IIS. IIS не поддерживает HTTP / 2.

То же верно и для служб приложений Azure. Они используют IIS, поэтому еще не поддерживают gRPC. Я подозреваю, что Microsoft добавит поддержку позже в этом году.

Спасибо за чтение и будьте в безопасности.