Предоставление локальной службы WCF для веб-приложения в облаке с помощью Azure Relay

В этой статье показано, как создать гибридное облачное приложение с помощью Microsoft Azure и Visual Studio. Вы создаете приложение, использующее несколько ресурсов Azure в облаке. Это руководство поможет вам узнать:

  • Как создать или адаптировать существующую веб-службу для использования веб-решением.
  • Как использовать службу ретрансляции Azure Windows Communication Foundation (WCF) для обмена данными между приложением Azure и веб-службой, размещенной в другом месте.

В этом учебнике вы выполните следующие задачи:

  • Установка обязательных компонентов для работы с этим учебником.
  • Просмотр сценария.
  • Создайте пространство имен.
  • Создание локального сервера.
  • Создание приложения ASP .NET.
  • Запустите приложение на локальном компьютере.
  • Разверните веб-приложение в Azure.
  • Запустите приложение в Azure.

Необходимые компоненты

Для работы с данным руководством вам потребуется:

  • Подписка Azure. Если у вас еще нет подписки Azure, создайте бесплатную учетную запись, прежде чем начать работу.
  • Visual Studio 2015 или более поздней версии. В примерах для этого учебника используется Visual Studio 2019.
  • Пакет Azure SDK для .NET. Установите его со страницы загрузки SDK.

Как ретранслятор Azure помогает работать с гибридными решениями

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

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

Azure Relay использует существующие веб-службы WCF и обеспечивает безопасный доступ к этим службам для решений, находящихся за пределами корпоративного периметра, без необходимости внесения навязчивых изменений в инфраструктуру корпоративной сети. Такие службы ретрансляции по-прежнему размещаются внутри существующей среды, однако они делегируют функции прослушивания входящих сеансов и запросов размещенной в облаке службе ретрансляции. Ретранслятор Azure также защищает эти службы от несанкционированного доступа, применяя аутентификацию на основе подписанного URL-адреса (SAS).

Просмотр сценария

В этом руководстве вы создадите веб-сайт ASP.NET, который позволит просматривать список продуктов на странице складских запасов.

Scenario

В учебнике предполагается, что у вас есть сведения о продуктах в существующей локальной системе, для доступа к которой используется ретранслятор Azure. Эту ситуацию имитирует веб-служба, работающая в простом консольном приложении. Она содержит набор продуктов в памяти. Вы можете запустить это консольное приложение на своем компьютере и развернуть веб-роль в Azure. Сделав это, вы увидите, как веб-роль, выполняемая в центре обработки данных Azure, обращается к вашему компьютеру. Этот вызов происходит даже в том случае, если ваш компьютер почти наверняка находится за хотя бы одним брандмауэром и уровнем трансляции сетевых адресов (NAT).

Настройка среды разработки

Прежде чем начать разработку приложения для Azure, скачайте нужные инструменты и настройте среду разработки.

  1. Установите пакет SDK Azure для .NET, скачав его с этой страницы.
  2. В столбце .NET выберите версию Visual Studio, которую вы используете. В этом руководстве используется Visual Studio 2019.
  3. Когда будет предложено запустить или сохранить установщик, выберите Выполнить.
  4. В диалоговом окне Установщик веб-платформы выберите Установить и продолжите установку.

После завершения установки у вас будет все необходимое, чтобы начать разработку приложения. В состав пакета SDK входят инструменты для эффективной разработки приложений Azure в Visual Studio.

Создание пространства имен

Сначала необходимо создать пространство имен и получить ключ подписанного URL-адреса (SAS). Пространство имен определяет границы каждого приложения, предоставляемого через службу ретрансляции. Ключ SAS автоматически создается системой при создании пространства имен службы. Сочетание пространства имен и ключа SAS образует учетные данные, на основе которых Azure осуществляет аутентификацию доступа к приложению.

  1. Войдите на портал Azure.

  2. В меню слева выберите Все службы. Выберите "Интеграция", найдите ретрансляторы, переместите указатель мыши на ретрансляторы и нажмите кнопку "Создать".

    Screenshot showing the selection of Relays -> Create button.

  3. На странице "Создание пространства имен" выполните следующие действия.

    1. Выберите подписку Azure, в которой будет создано пространство имен.

    2. Выберите существующую группу ресурсов, в которую будет размещено это пространство имен, или создайте новую.

    3. Введите имя пространства имен Ретранслятора.

    4. Выберите регион, в котором должно размещаться пространство имен.

    5. В нижней части страницы выберите Review + create (Проверить и создать).

      Screenshot showing the Create namespace page.

    6. На странице Отзыв и создание выберите Создать.

    7. Через несколько минут вы увидите страницу Ретранслятора для пространства имен.

      Screenshot showing the home page for Relay namespace.

Получение учетных данных управления

  1. На странице "Ретранслятор" выберите политики общего доступа в меню слева. `

  2. На странице Политики общего доступа щелкните RootManageSharedAccessKey.

  3. В разделе SAS Policy: RootManageSharedAccessKey (Политика SAS: RootManageSharedAccessKey) нажмите кнопку Копировать рядом с элементом Первичная строка подключения. Строка подключения будет скопирована в буфер обмена для дальнейшего использования. Вставьте на время эти значения в Блокноте или любом другом месте.

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

    Screenshot showing the connection info for Relay namespace.

Создание локального сервера

Во-первых, вы создадите имитированную локальную систему каталогов продукции. Этот проект запускается как консольное приложение Visual Studio, используя пакет NuGet служебной шины Azure для включения библиотек и параметров конфигурации служебной шины.

  1. Запустите Microsoft Visual Studio от имени администратора. Для этого щелкните правой кнопкой мыши значок программы Visual Studio и выберите Запустить от имени администратора.

  2. В Visual Studio выберите Создать проект.

  3. В разделе Создать новый проект выберите Консольное приложение (.NET Framework) для C# и нажмите Далее.

  4. Назовите проект ProductsServer и нажмите Создать.

    Configure your new project

  5. В Обозревателе решений щелкните правой кнопкой мыши проект ProductsServer и выберите Управление пакетами NuGet.

  6. Нажмите Обзор, найдите и выберите WindowsAzure.ServiceBus. Нажмите Установить и примите условия использования.

    Select NuGet package

    На необходимые клиентские сборки теперь имеется ссылка.

  7. Добавьте новый класс для контракта на свою продукцию. В Обозревателе решений щелкните правой кнопкой мыши проект ProductsServer и выберите Добавить>Класс.

  8. В поле Имя введите имя ProductsContract.cs и выберите Добавить.

Внесите следующие изменения в код решения:

  1. В ProductsContract.cs замените определение пространства имен на приведенный ниже код, определяющий контракт для службы.

    namespace ProductsServer
    {
        using System.Collections.Generic;
        using System.Runtime.Serialization;
        using System.ServiceModel;
    
        // Define the data contract for the service
        [DataContract]
        // Declare the serializable properties.
        public class ProductData
        {
            [DataMember]
            public string Id { get; set; }
            [DataMember]
            public string Name { get; set; }
            [DataMember]
            public string Quantity { get; set; }
        }
    
        // Define the service contract.
        [ServiceContract]
        interface IProducts
        {
            [OperationContract]
            IList<ProductData> GetProducts();
    
        }
    
        interface IProductsChannel : IProducts, IClientChannel
        {
        }
    }
    
  2. В Program.cs замените определение пространства имен следующим кодом, который добавляет службу профиля и хост для нее.

    namespace ProductsServer
    {
        using System;
        using System.Linq;
        using System.Collections.Generic;
        using System.ServiceModel;
    
        // Implement the IProducts interface.
        class ProductsService : IProducts
        {
    
            // Populate array of products for display on website
            ProductData[] products =
                new []
                    {
                        new ProductData{ Id = "1", Name = "Rock",
                                         Quantity = "1"},
                        new ProductData{ Id = "2", Name = "Paper",
                                         Quantity = "3"},
                        new ProductData{ Id = "3", Name = "Scissors",
                                         Quantity = "5"},
                        new ProductData{ Id = "4", Name = "Well",
                                         Quantity = "2500"},
                    };
    
            // Display a message in the service console application
            // when the list of products is retrieved.
            public IList<ProductData> GetProducts()
            {
                Console.WriteLine("GetProducts called.");
                return products;
            }
    
        }
    
        class Program
        {
            // Define the Main() function in the service application.
            static void Main(string[] args)
            {
                var sh = new ServiceHost(typeof(ProductsService));
                sh.Open();
    
                Console.WriteLine("Press ENTER to close");
                Console.ReadLine();
    
                sh.Close();
            }
        }
    }
    
  3. В обозревателе решений дважды щелкните файл App.config, чтобы открыть его в редакторе Visual Studio. В нижней части элемента <system.ServiceModel>, но все еще внутри <system.ServiceModel> добавьте следующий код XML.

    Важно!

    Замените yourServiceNamespace именем пространства имен и yourKey ключом SAS, полученным ранее на портале:

      <services>
         <service name="ProductsServer.ProductsService">
           <endpoint address="sb://yourServiceNamespace.servicebus.windows.net/products" binding="netTcpRelayBinding" contract="ProductsServer.IProducts" behaviorConfiguration="products"/>
         </service>
      </services>
      <behaviors>
         <endpointBehaviors>
           <behavior name="products">
             <transportClientEndpointBehavior>
                <tokenProvider>
                   <sharedAccessSignature keyName="RootManageSharedAccessKey" key="yourKey" />
                </tokenProvider>
             </transportClientEndpointBehavior>
           </behavior>
         </endpointBehaviors>
      </behaviors>
    

    Примечание.

    Ошибка, вызванная transportClientEndpointBehavior, является просто предупреждением и в этом примере не является проблемой блокировки.

  4. По-прежнему в App.config в элементе <appSettings> замените значение строки подключения на строку подключения, полученную ранее с портала.

    <appSettings>
       <!-- Service Bus specific app settings for messaging connections -->
       <add key="Microsoft.ServiceBus.ConnectionString"
           value="Endpoint=sb://yourNamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=yourKey"/>
    </appSettings>
    
  5. Нажмите клавиши Ctrl+Shift+B или выберите Сборка>Решение сборки, чтобы создать приложение и проверить точность вашей работы на данный момент.

Создание приложения ASP.NET

В этом разделе вы создадите простое приложение ASP.NET, которое будет отображать данные, полученные из службы продукции.

Создание проекта

  1. Убедитесь, что Visual Studio запущена от имени администратора.

  2. В Visual Studio выберите Создать проект.

  3. В разделе Создать новый проект выберите Веб-приложение ASP.NET (.NET Framework) для C# и нажмите Далее.

  4. Назовите проект ProductsPortal и выберите Создать.

  5. В разделе Создание нового веб-приложения ASP.NET выберите MVC и выберите Изменить в разделе Проверка подлинности.

    Select ASP .NET Web Application

  6. В разделе Изменить аутентификацию выберите Без аутентификации, затем нажмите OK. В этом руководстве вы развертываете приложение, для которого не требуется вход пользователя.

    Specify authentication

  7. Вернувшись в раздел Создание нового веб-приложения ASP.NET, выберите Создать, чтобы создать приложение MVC.

  8. Настройте ресурсы Azure для нового веб-приложения. Следуйте инструкциям в разделе Приложения вашего веб-приложение. Затем вернитесь к этому руководству и перейдите к следующему шагу.

  9. В Обозревателе решений щелкните правой кнопкой мыши Модели и выберите Добавить>Класс.

  10. Назовите класс Product.cs, затем выберите Добавить.

    Create Product model

Изменение веб-приложения

  1. В файле Product.cs в Visual Studio замените существующее определение пространства имен следующим кодом:

     // Declare properties for the products inventory.
     namespace ProductsWeb.Models
     {
        public class Product
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public string Quantity { get; set; }
        }
     }
    
  2. В Обозревателе решений разверните Контроллеры, затем дважды щелкните HomeController.cs, чтобы открыть файл в Visual Studio.

  3. В файле HomeController.cs замените имеющееся определение пространства имен следующим кодом:

    namespace ProductsWeb.Controllers
    {
        using System.Collections.Generic;
        using System.Web.Mvc;
        using Models;
    
        public class HomeController : Controller
        {
            // Return a view of the products inventory.
            public ActionResult Index(string Identifier, string ProductName)
            {
                var products = new List<Product>
                    {new Product {Id = Identifier, Name = ProductName}};
                return View(products);
            }
         }
    }
    
  4. В Обозревателе решений разверните Представления>Общие, затем дважды щелкните _Layout.cshtml, чтобы открыть файл в редакторе Visual Studio.

  5. Измените все происшествия My ASP.NET Application на Northwind Traders Products.

  6. Удалите ссылки Home, About и Contact. В следующем примере удалите выделенный код.

    Delete the generated list items

  7. В Обозревателе решений разверните Представления>Главная, затем дважды щелкните Index.cshtml, чтобы открыть файл в редакторе Visual Studio. Замените все содержимое файла следующим кодом:

    @model IEnumerable<ProductsWeb.Models.Product>
    
    @{
             ViewBag.Title = "Index";
    }
    
    <h2>Prod Inventory</h2>
    
    <table>
              <tr>
                  <th>
                      @Html.DisplayNameFor(model => model.Name)
                  </th>
                  <th></th>
                  <th>
                      @Html.DisplayNameFor(model => model.Quantity)
                  </th>
              </tr>
    
    @foreach (var item in Model) {
              <tr>
                  <td>
                      @Html.DisplayFor(modelItem => item.Name)
                  </td>
                  <td>
                      @Html.DisplayFor(modelItem => item.Quantity)
                  </td>
              </tr>
    }
    
    </table>
    
  8. Чтобы проверить точность вашей работы на данный момент, вы можете выбрать Ctrl+Shift+B для сборки проекта.

Локальный запуск приложения

Запустите приложение, чтобы убедиться, что оно работает.

  1. ProductsPortal должен быть активным проектом. Щелкните правой кнопкой мыши имя проекта в Обозревателе решений и выберите Установить как запускаемый проект.
  2. В Visual Studio выберите F5.

Приложение должно начать выполняться в браузере.

Screenshot shows an example of the application running in a browser with the URL highlighted.

Объединение элементов

Следующим шагом является подключение локального сервера продуктов к приложению ASP.NET.

  1. Если он еще не открыт, в Visual Studio откройте проект ProductsPortal, созданный в разделе Создание приложения ASP.NET.

  2. Как и в шаге в разделе Создание локального сервера, добавьте пакет NuGet в ссылки на проект. В Обозревателе решений щелкните правой кнопкой мыши проект ProductsPortal и выберите Управление пакетами NuGet.

  3. Выполните поиск по фразе WindowsAzure.ServiceBus и выберите элемент WindowsAzure.ServiceBus. Затем завершите установку и закройте это диалоговое окно.

  4. В Обозревателе решений щелкните правой кнопкой мыши проект ProductsPortal и выберите Добавить>Существующий элемент.

  5. Перейдите к файлу ProductsContract.cs в консольном проекте ProductsServer. Выделите ProductsContract.cs. Щелкните стрелку вниз рядом с кнопкой Добавить, затем выберите Добавить как ссылку.

    Add as a link

  6. Теперь откройте файл HomeController.cs в редакторе Visual Studio и замените существующее определение пространства имен приведенным ниже кодом. Обязательно замените yourServiceNamespace имя пространства имен Ретранслятора и yourKey ключом SAS. Этот код позволяет клиенту вызывать локальную службу, возвращая результат вызова.

    namespace ProductsWeb.Controllers
    {
        using System.Linq;
        using System.ServiceModel;
        using System.Web.Mvc;
        using Microsoft.ServiceBus;
        using Models;
        using ProductsServer;
    
        public class HomeController : Controller
        {
            // Declare the channel factory.
            static ChannelFactory<IProductsChannel> channelFactory;
    
            static HomeController()
            {
                // Create shared access signature token credentials for authentication.
                channelFactory = new ChannelFactory<IProductsChannel>(new NetTcpRelayBinding(),
                    "sb://yourServiceNamespace.servicebus.windows.net/products");
                channelFactory.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior {
                    TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
                        "RootManageSharedAccessKey", "yourKey") });
            }
    
            public ActionResult Index()
            {
                using (IProductsChannel channel = channelFactory.CreateChannel())
                {
                    // Return a view of the products inventory.
                    return this.View(from prod in channel.GetProducts()
                                     select
                                         new Product { Id = prod.Id, Name = prod.Name,
                                             Quantity = prod.Quantity });
                }
            }
        }
    }
    
  7. В Обозревателе решений щелкните правой кнопкой мыши решение ProductsPortal. Обязательно щелкните правой кнопкой мыши решение, а не проект. Выберите Добавить>Существующий проект.

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

  9. ProductsServer должен быть запущен для отображения данных на ProductsPortal. В Обозревателе решений щелкните правой кнопкой мыши решение ProductsPortal и выберите Свойства, чтобы отобразить Страницы свойств.

  10. Выберите Общие свойства>Запускаемый проект, затем выберите Несколько запускаемых проектов. Убедитесь, что ProductsServer и ProductsPortal отображаются в указанном порядке и что Действие для обоих — Запустить.

    Multiple startup projects

  11. Выберите Общие свойства>Зависимости проекта в левой части.

  12. Для Проектов выберите ProductsPortal. Установите флажок ProductsServer.

    Project dependencies

  13. Для Проектов выберите ProductsServer. Убедитесь, что ProductsPortal не выбран, а затем нажмите кнопку ОК, чтобы сохранить изменения.

Локальный запуск проекта

Чтобы протестировать приложение локально, в Visual Studio выберите F5. Первым должен запуститься локальный сервер ProductsServer, а затем в окне браузера должно запуститься приложение ProductsPortal. На этот раз вы сможете проследить получение данных списка складских запасов продукции из локальной системы службы продукции.

Web application

Выберите Обновить на странице ProductsPortal. При каждом обновлении страницы после вызова GetProducts() из ProductsServer в серверном приложении будет отображаться сообщение.

Закройте оба приложения, прежде чем переходить к следующему разделу.

Развертывание проекта ProductsPortal в веб-приложении Azure

Следующим шагом является повторная публикация внешнего интерфейса ProductsPortal веб-приложения Azure:

  1. В Обозревателе решений щелкните правой кнопкой мыши проект ProductsPortal и выберите Опубликовать. На странице Публикация нажмите кнопку Опубликовать.

    Примечание.

    Если веб-проект ProductsPortal запустится после развертывания автоматически, в окне браузера может появиться сообщение об ошибке. Это ожидаемое поведение, и означает, что приложение ProductsServer еще не запущено.

  2. Скопируйте URL-адрес развернутого веб-приложения. URL вам понадобится позже. Вы также можете получить этот URL-адрес из окна активности службы приложений Azure в Visual Studio:

    URL of the deployed app

  3. Закройте окно браузера, чтобы остановить выполняющееся приложение.

Перед запуском приложения в облаке необходимо убедиться, что ProductsPortal запущен из Visual Studio как веб-приложение.

  1. В Visual Studio щелкните правой кнопкой мыши проект ProductsPortal и выберите Свойства.

  2. Выберите Интернет. В разделе Действие при запускевыберите Начальный URL-адрес. Введите URL-адрес вашего ранее развернутого веб-приложения в этом примере https://productsportal20190906122808.azurewebsites.net/.

    Start URL

  3. Нажмите Файл>Сохранить все.

  4. Выберите Сборка>Перестроение решения.

Выполнение приложения

Выберите F5, чтобы построить и запустить приложение. Локальный сервер, который является консольным приложением ProductsServer, должен запуститься первым, затем приложение ProductsPortal должно запуститься в окне браузера, как показано здесь:

Run the web app on Azure

В инвентаре продуктов перечислены данные, полученные из локальной системы обслуживания продуктов, и эти данные отображаются в веб-приложении. Проверьте URL-адрес. Приложение ProductsPortal должно запускаться в облаке как веб-приложение Azure.

Важно!

Консольное приложение ProductsServer должно запускаться с возможностью передачи данных в приложение ProductsPortal. Если в браузере отображается ошибка, подождите еще несколько секунд, пока ProductsServer загрузится и отобразит следующее сообщение, а затем обновите браузер.

В браузере обновите страницу ProductsPortal. При каждом обновлении страницы после вызова GetProducts() из ProductsServer в серверном приложении будет отображаться сообщение.

Updated output

Следующие шаги

Перейдите к следующему руководству: