자습서: Azure WCF Relay REST 자습서

이 자습서에서는 REST 기반 인터페이스를 표시하는 Azure Relay 호스트 애플리케이션을 빌드하는 방법을 설명합니다. REST는 웹 브라우저와 같은 웹 클라이언트가 HTTP 요청을 통해 Service Bus API에 액세스할 수 있도록 합니다.

자습서에서는 WCF(Windows Communication Foundation) REST 프로그래밍 모델을 사용하여 Azure Relay에 REST 서비스를 구축합니다. 자세한 내용은 WCF REST 프로그래밍 모델서비스 디자인 및 구현을 참조하세요.

이 자습서에서는 다음 작업을 수행합니다.

  • 이 자습서를 수행하기 위한 필수 조건 설치
  • Relay 네임스페이스 만들기
  • REST 기반 WCF 서비스 계약 정의
  • REST 기반 WCF 계약 구현
  • REST 기반 WCF 서비스 호스트 및 실행
  • 서비스 실행 및 테스트

필수 조건

이 자습서를 완료하려면 다음 필수 구성 요소가 필요합니다.

Relay 네임스페이스 만들기

Azure에서 릴레이 기능 사용을 시작하려면 먼저 서비스 네임스페이스를 만들어야 합니다. 네임스페이스는 애플리케이션 내에서 Azure 리소스의 주소를 지정하기 위한 범위 컨테이너를 제공합니다. 여기의 지침을 따라 릴레이 네임스페이스를 만듭니다.

Azure Relay와 사용할 REST 기반 WCF 서비스 계약 정의

WCF REST 스타일 서비스를 만들 때 계약을 정의해야 합니다. 계약은 호스트가 지원하는 작업을 지정합니다. 서비스 작업은 웹 서비스 메서드와 비슷합니다. C++, C# 또는 Visual Basic 인터페이스를 사용하여 계약을 정의합니다. 인터페이스의 각 메서드는 특정 서비스 작업에 해당합니다. 각 인터페이스에 ServiceContractAttribute 특성을 적용하고, 각 작업에 OperationContractAttribute 특성을 적용합니다.

ServiceContractAttribute 특성이 있는 인터페이스의 메서드에 OperationContractAttribute 특성이 없으면 해당 메서드가 표시되지 않습니다. 이러한 작업에 사용되는 코드는 절차를 수행하면서 예제에 표시됩니다.

WCF 계약과 REST 스타일 계약의 주요 차이는 OperationContractAttribute: WebGetAttribute에 대한 속성의 추가합니다. 이 속성을 사용하면 인터페이스의 메서드를 인터페이스 반대편의 메서드로 매핑할 수 있습니다. 이 예제에서는 WebGetAttribute 특성을 사용하여 메서드를 HTTP GET에 연결합니다. 이 접근 방식을 사용하면 Service Bus가 인터페이스로 전송된 명령을 정확하게 검색하고 해석할 수 있습니다.

인터페이스와 함께 계약을 만들려면

  1. 관리자 권한으로 Microsoft Visual Studio를 시작합니다. 이렇게 하려면 Visual Studio 프로그램 아이콘을 마우스 오른쪽 단추로 클릭하고 관리자 권한으로 실행을 선택합니다.

  2. Visual Studio에서 새 프로젝트 만들기를 선택합니다.

  3. 새 프로젝트 만들기에서 C#용 콘솔 앱(.NET Framework)을 선택하고, 다음을 선택합니다.

  4. 프로젝트 이름을 ImageListener로 지정합니다. 기본 위치를 사용하고, 만들기를 선택합니다.

    C# 프로젝트의 경우 Visual Studio에서 Program.cs 파일을 만듭니다. 이 클래스는 콘솔 애플리케이션 프로젝트를 제대로 구축하는데 필요한 빈 Main() 메서드를 포함합니다.

  5. 솔루션 탐색기에서 ImageListener 프로젝트를 마우스 오른쪽 단추로 클릭한 다음, NuGet 패키지 관리를 선택합니다.

  6. 찾아보기를 선택한 다음, WindowsAzure.ServiceBus를 검색하여 선택합니다. 설치를 선택하고 사용 약관에 동의합니다.

    이 단계에서는 Service Bus 및 System.ServiceModel.dll에 대한 참조를 추가합니다. 이 패키지는 Service Bus 라이브러리 및 WCF System.ServiceModel에 대한 참조를 자동으로 추가합니다.

  7. System.ServiceModel.Web.dll에 대한 참조를 프로젝트에 명시적으로 추가합니다. 솔루션 탐색기에서 프로젝트 폴더 아래의 참조 폴더를 마우스 오른쪽 단추로 클릭하고, 참조 추가를 선택합니다.

  8. 참조 추가에서 Framework를 선택하고, 검색System.ServiceModel.Web을 입력합니다. System.ServiceModel.Web 확인란을 선택한 다음 확인을 선택합니다.

그리고 프로젝트의 코드를 다음과 같이 변경합니다.

  1. Program.cs 파일 맨 위에 다음 using 문을 추가합니다.

    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.IO;
    
    • System.ServiceModel은 WCF의 기본 기능에 프로그래밍 방식의 액세스를 가능하게 하는 네임스페이스입니다. WCF 릴레이는 WCF의 많은 개체와 특성을 사용하여 서비스 계약을 정의합니다. 이 네임스페이스는 대부분의 릴레이 애플리케이션에서 사용됩니다.
    • System.ServiceModel.Channels는 채널을 정의하는 데 도움이 되며, 이 개체를 통해 Azure Relay 및 클라이언트 웹 브라우저와 통신하게 됩니다.
    • System.ServiceModel.Web에는 웹 기반 애플리케이션을 만들 수 있는 형식이 포함되어 있습니다.
  2. ImageListener 네임스페이스 이름을 Microsoft.ServiceBus.Samples로 변경합니다.

    namespace Microsoft.ServiceBus.Samples
    {
        ...
    
  3. 네임스페이스 선언의 중괄호를 연 바로 다음에 IImageContract라는 새 인터페이스를 정의하고 이 인터페이스에 ServiceContractAttribute 특성의 값을 https://samples.microsoft.com/ServiceModel/Relay/RESTTutorial1로 적용합니다.

    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/RESTTutorial1")]
    public interface IImageContract
    {
    }
    

    네임스페이스 값은 코드 전반에 사용하는 네임스페이스에 따라 다릅니다. 네임스페이스 값은 이 계약의 고유 식별자이며 버전 정보가 있어야 합니다. 자세한 내용은 서비스 버전 관리를 참조하세요. 네임스페이스를 명시적으로 지정하면 기본 네임스페이스 값이 계약 이름에 추가되는 경우를 방지합니다.

  4. IImageContract 인터페이스 내에서 IImageContract 계약이 인터페이스에 노출하는 단일 작업에 대한 메서드를 선언하고, 공개 Service Bus 계약의 일부로 노출하려는 메서드에 OperationContract 특성을 적용합니다.

    public interface IImageContract
    {
        [OperationContract]
        Stream GetImage();
    }
    
  5. OperationContract 특성에서 WebGet 값을 추가합니다.

    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }
    

    WebGet 값을 추가하면 릴레이 서비스가 HTTP GET 요청을 GetImage로 라우팅하고 GetImage의 반환 값을 HTTP GETRESPONSE 회신으로 해석할 수 있습니다. 이 자습서의 뒷부분에서는 웹 브라우저를 사용하여 이 메서드에 액세스하고, 브라우저에 이미지를 표시할 것입니다.

  6. IImageContract 정의 바로 다음에 IImageContractIClientChannel 인터페이스로부터 상속되는 채널을 선언합니다.

    public interface IImageChannel : IImageContract, IClientChannel { }
    

    채널은 서비스 및 클라이언트가 서로 정보를 전달하는 WCF 개체입니다. 나중에 호스트 애플리케이션에서 채널을 만듭니다. 그러면 Azure Relay는 이 채널을 사용하여 브라우저의 HTTP GET 요청을 GetImage 구현으로 전달합니다. 릴레이는 이 채널을 사용하여 GetImage 반환 값을 가져와서 클라이언트 브라우저에 대한 HTTP GETRESPONSE로 해석하기도 합니다.

  7. 빌드>솔루션 빌드를 선택하여 지금까지 수행한 작업이 정확한지 확인합니다.

WCF Relay 계약을 정의하는 예제

다음 코드는 WCF 릴레이 계약을 정의하는 기본 인터페이스를 보여 줍니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;

namespace Microsoft.ServiceBus.Samples
{

    [ServiceContract(Name = "IImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

REST 기반 WCF 서비스 계약 구현

REST 스타일 WCF Relay 서비스를 만들려면 먼저 인터페이스를 사용하여 계약을 만듭니다. 다음 단계에는 인터페이스를 구현합니다. 이 절차에는 사용자 정의 IImageContract 인터페이스를 구현하는 이름이 ImageService인 클래스를 만드는 단계가 포함됩니다. 계약을 구현한 후에는 App.config 파일을 사용하여 인터페이스를 구현합니다. 구성 파일에는 애플리케이션에 필요한 정보가 포함되어 있습니다. 이 정보에는 서비스 이름, 계약 이름, 릴레이 서비스와 통신하는 데 사용되는 프로토콜 유형이 있습니다. 이러한 작업에 사용되는 코드는 절차를 수행하면서 예제에 표시됩니다.

이전 단계와 마찬가지로, REST 스타일 계약과 WCF Relay 계약의 구현 간에는 거의 차이가 없습니다.

REST 스타일 Service Bus 계약을 구현하려면

  1. IImageContract 인터페이스 정의 바로 뒤에 이름이 ImageService인 클래스를 새로 만듭니다. ImageService 클래스가 IImageContract 인터페이스를 구현합니다.

    class ImageService : IImageContract
    {
    }
    

    다른 인터페이스 구현과 유사하게, 다른 파일에 정의를 구현할 수 있습니다. 하지만 이 자습서의 경우 구현은 인터페이스 정의 및 Main() 메서드와 동일한 파일에서 나타납니다.

  2. ServiceBehaviorAttribute 특성을 IImageService 클래스에 적용하여 클래스가 WCF 계약의 구현이라는 것을 나타냅니다.

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
    }
    

    앞서 설명했듯이, 이 네임스페이스는 기존의 네임스페이스가 아니라 계약을 식별하는 WCF 아키텍처의 일부입니다. 자세한 내용은 데이터 계약 이름을 참조하세요.

  3. .jpg 이미지를 프로젝트에 추가합니다. 이 파일은 서비스가 수신 브라우저에 표시하는 그림입니다.

    1. 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택합니다.
    2. 그리고 기존 항목을 선택합니다.
    3. 기존 항목 추가를 사용하여 적절한 .jpg를 찾은 다음, 추가를 선택합니다. 파일을 추가할 때 파일 이름 옆에 있는 드롭다운 목록에서 모든 파일을 선택합니다.

    이 자습서의 나머지 부분에서는 이미지의 이름을 image.jpg로 가정합니다. 다른 파일이 있으면 이미지 이름을 변경하거나 보완하도록 코드를 변경해야 합니다.

  4. 실행 중인 서비스가 이미지 파일을 반드시 찾게 하려면 솔루션 탐색기에서 이미지 파일을 마우스 오른쪽 단추로 클릭한 다음, 속성을 선택합니다. 속성에서 출력 디렉터리로 복사변경된 내용만 복사로 설정합니다.

  5. 인터페이스와 함께 계약을 만들려면의 절차를 사용하여 System.Drawing.dll 어셈블리에 대한 참조를 프로젝트에 추가합니다.

  6. 관련된 다음 using 문을 추가합니다.

    using System.Drawing;
    using System.Drawing.Imaging;
    using Microsoft.ServiceBus;
    using Microsoft.ServiceBus.Web;
    
  7. ImageService 클래스에서 비트맵을 로드하는 다음 생성자를 추가하고, 이 생성자를 클라이언트 브라우저로 보낼 준비를 합니다.

    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";
    
        Image bitmap;
    
        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }
    }
    
  8. 이전 코드 바로 뒤에서, 이미지를 포함하는 HTTP 메시지를 반환하는 다음 GetImage 메서드를 ImageService 클래스에 추가합니다.

    public Stream GetImage()
    {
        MemoryStream stream = new MemoryStream();
        this.bitmap.Save(stream, ImageFormat.Jpeg);
    
        stream.Position = 0;
        WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
    
        return stream;
    }
    

    이 구현은 MemoryStream을 사용하여 이미지를 가져온 후 브라우저로 스트리밍할 준비를 합니다. 또한 0에서 스트림 위치를 시작하고, 스트림 콘텐츠를 .jpg로 선언하고, 정보를 스트리밍합니다.

  9. 빌드>솔루션 빌드를 선택합니다.

Service Bus에서 웹 서비스를 실행하기 위한 구성을 정의하려면

  1. 솔루션 탐색기에서 App.config 파일을 두 번 클릭하여 Visual Studio 편집기에서 엽니다.

    App.config 파일에는 서비스 이름, 엔드포인트 및 바인딩이 들어 있습니다. 엔드포인트는 클라이언트와 호스트가 서로 통신할 수 있도록 Azure Relay가 노출하는 위치입니다. 바인딩은 통신에 사용되는 프로토콜 유형입니다. 여기서 주요 차이점은 구성된 서비스 엔드포인트가 WebHttpRelayBinding 바인딩을 참조한다는 것입니다.

  2. <system.serviceModel> XML 요소는 하나 이상의 서비스를 정의하는 WCF 요소입니다. 여기서는 서비스 이름 및 엔드포인트를 정의하는데 사용됩니다. <system.serviceModel> 요소의 맨 아래에(하지만 여전히 <system.serviceModel> 내에서) 다음 콘텐츠를 포함하는 <bindings> 요소를 추가합니다.

    <bindings>
        <!-- Application Binding -->
        <webHttpRelayBinding>
            <binding name="default">
                <security relayClientAuthenticationType="None" />
            </binding>
        </webHttpRelayBinding>
    </bindings>
    

    이 콘텐츠는 애플리케이션에서 사용되는 바인딩을 정의합니다. 여러 바인딩을 정의할 수 있지만, 이 자습서에서는 하나만 정의합니다.

    이전 코드는 relayClientAuthenticationTypeNone으로 설정된 WCF Relay WebHttpRelayBinding 바인딩을 정의합니다. 이 설정은 이 바인딩을 사용하는 엔드포인트에 클라이언트 자격 증명이 필요 없다는 것을 나타냅니다.

  3. <bindings> 요소 다음에 <services> 요소를 추가합니다. 바인딩과 유사하게 단일 구성 파일 내에 여러 서비스를 정의할 수 있습니다. 하지만 이 자습서에서는 하나만 정의합니다.

    <services>
        <!-- Application Service -->
        <service name="Microsoft.ServiceBus.Samples.ImageService"
             behaviorConfiguration="default">
            <endpoint name="RelayEndpoint"
                    contract="Microsoft.ServiceBus.Samples.IImageContract"
                    binding="webHttpRelayBinding"
                    bindingConfiguration="default"
                    behaviorConfiguration="sbTokenProvider"
                    address="" />
        </service>
    </services>
    

    이 콘텐츠는 이전에 정의된 기본 webHttpRelayBinding을 사용하는 서비스를 구성합니다. 기본 sbTokenProvider도 사용하며, 이것은 다음 단계에서 정의됩니다.

  4. <services> 요소 후에는 다음 콘텐츠를 사용하여 <behaviors> 요소를 만들고, SAS_KEY를 SAS(공유 액세스 서명) 키로 바꿉니다. Azure Portal에서 SAS 키를 얻으려면 관리 자격 증명 가져오기를 참조하세요.

    <behaviors>
        <endpointBehaviors>
            <behavior name="sbTokenProvider">
                <transportClientEndpointBehavior>
                    <tokenProvider>
                        <sharedAccessSignature keyName="RootManageSharedAccessKey" key="YOUR_SAS_KEY" />
                    </tokenProvider>
                </transportClientEndpointBehavior>
            </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior name="default">
                    <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" />
                </behavior>
            </serviceBehaviors>
    </behaviors>
    
  5. 계속 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=YOUR_SAS_KEY"/>
    </appSettings>
    
  6. 빌드>솔루션 빌드를 선택하여 전체 솔루션을 빌드합니다.

REST 기반 WCF 서비스 계약을 구현하는 예제

다음 코드는 WebHttpRelayBinding 바인딩을 사용하여 Service Bus에서 실행되는 REST 기반 서비스에 대한 계약 및 서비스 구현을 보여줍니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;

namespace Microsoft.ServiceBus.Samples
{


    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";

        Image bitmap;

        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }

        public Stream GetImage()
        {
            MemoryStream stream = new MemoryStream();
            this.bitmap.Save(stream, ImageFormat.Jpeg);

            stream.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";

            return stream;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

다음 예제에서는 서비스와 관련된 App.config 파일을 보여줍니다.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
    </startup>
    <system.serviceModel>
        <extensions>
            <!-- In this extension section we are introducing all known service bus extensions. User can remove the ones they don't need. -->
            <behaviorExtensions>
                <add name="connectionStatusBehavior"
                    type="Microsoft.ServiceBus.Configuration.ConnectionStatusElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="transportClientEndpointBehavior"
                    type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="serviceRegistrySettings"
                    type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </behaviorExtensions>
            <bindingElementExtensions>
                <add name="netMessagingTransport"
                    type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus,  Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="tcpRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.TcpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="httpRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.HttpRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="httpsRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.HttpsRelayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="onewayRelayTransport"
                    type="Microsoft.ServiceBus.Configuration.RelayedOnewayTransportElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </bindingElementExtensions>
            <bindingExtensions>
                <add name="basicHttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="webHttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="ws2007HttpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netTcpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netOnewayRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netEventRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
                <add name="netMessagingBinding"
                    type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            </bindingExtensions>
        </extensions>
      <bindings>
        <!-- Application Binding -->
        <webHttpRelayBinding>
          <binding name="default">
            <security relayClientAuthenticationType="None" />
          </binding>
        </webHttpRelayBinding>
      </bindings>
      <services>
        <!-- Application Service -->
        <service name="Microsoft.ServiceBus.Samples.ImageService"
             behaviorConfiguration="default">
          <endpoint name="RelayEndpoint"
                  contract="Microsoft.ServiceBus.Samples.IImageContract"
                  binding="webHttpRelayBinding"
                  bindingConfiguration="default"
                  behaviorConfiguration="sbTokenProvider"
                  address="" />
        </service>
      </services>
      <behaviors>
        <endpointBehaviors>
          <behavior name="sbTokenProvider">
            <transportClientEndpointBehavior>
              <tokenProvider>
                <sharedAccessSignature keyName="RootManageSharedAccessKey" key="YOUR_SAS_KEY" />
              </tokenProvider>
            </transportClientEndpointBehavior>
          </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
          <behavior name="default">
            <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    <appSettings>
        <!-- Service Bus specific app settings for messaging connections -->
        <add key="Microsoft.ServiceBus.ConnectionString"
            value="Endpoint=sb://yourNamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=YOUR_SAS_KEY>"/>
    </appSettings>
</configuration>

Azure Relay를 사용하기 위해 REST 기반 WCF 서비스 호스팅

이 섹션에서는 WCF Relay와 함께 콘솔 애플리케이션을 사용하여 웹 서비스를 실행하는 방법을 설명합니다. 이 섹션에서 작성하는 전체 코드 목록은 절차를 수행하면서 예제에 제공됩니다.

서비스에 대한 기본 주소를 만들려면

  1. Main() 함수 선언에서 프로젝트의 네임스페이스를 저장할 변수를 만듭니다. yourNamespace를 이전에 만든 릴레이 네임스페이스의 이름으로 바꿔야 합니다.

    string serviceNamespace = "yourNamespace";
    

    Service Bus는 네임스페이스 이름을 사용하여 고유 URI를 만듭니다.

  2. 네임스페이스를 기반으로 하는 서비스 기본 주소에 대한 Uri 인스턴스를 만듭니다.

    Uri address = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, "Image");
    

웹 서비스 호스트를 만들고 구성하려면

계속 Main()에서, 이 섹션의 앞부분에서 만든 URI 주소를 사용하여 웹 서비스 호스트를 만듭니다.

WebServiceHost host = new WebServiceHost(typeof(ImageService), address);

서비스 호스트는 호스트 애플리케이션을 인스턴스화하는 WCF 개체입니다. 이 예제는 만들려는 호스트 형식(ImageService)과 호스트 애플리케이션을 노출하려는 주소를 전달합니다.

웹 서비스 호스트를 실행하려면

  1. 아직 Main()에 있는 경우 다음 줄을 추가하여 서비스를 엽니다.

    host.Open();
    

    이제 서비스가 실행 중입니다.

  2. 서비스가 실행 중임을 나타내고 서비스를 중지하는 방법을 알리는 메시지를 표시합니다.

    Console.WriteLine("Copy the following address into a browser to see the image: ");
    Console.WriteLine(address + "GetImage");
    Console.WriteLine();
    Console.WriteLine("Press [Enter] to exit");
    Console.ReadLine();
    
  3. 완료되면 서비스 호스트를 닫습니다.

    host.Close();
    

서비스 계약 및 구현 예제

다음 예제는 자습서에 포함된 이전 단계의 구현 및 서비스 계약을 포함하고 콘솔 애플리케이션에 서비스를 호스트합니다. 다음 코드를 이름이 ImageListener.exe인 실행 파일로 컴파일합니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Web;

namespace Microsoft.ServiceBus.Samples
{

    [ServiceContract(Name = "ImageContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IImageContract
    {
        [OperationContract, WebGet]
        Stream GetImage();
    }

    public interface IImageChannel : IImageContract, IClientChannel { }

    [ServiceBehavior(Name = "ImageService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class ImageService : IImageContract
    {
        const string imageFileName = "image.jpg";

        Image bitmap;

        public ImageService()
        {
            this.bitmap = Image.FromFile(imageFileName);
        }

        public Stream GetImage()
        {
            MemoryStream stream = new MemoryStream();
            this.bitmap.Save(stream, ImageFormat.Jpeg);

            stream.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";

            return stream;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string serviceNamespace = "InsertServiceNamespaceHere";
            Uri address = ServiceBusEnvironment.CreateServiceUri("https", serviceNamespace, "Image");

            WebServiceHost host = new WebServiceHost(typeof(ImageService), address);
            host.Open();

            Console.WriteLine("Copy the following address into a browser to see the image: ");
            Console.WriteLine(address + "GetImage");
            Console.WriteLine();
            Console.WriteLine("Press [Enter] to exit");
            Console.ReadLine();

            host.Close();
        }
    }
}

서비스 실행 및 테스트

솔루션을 빌드한 후 다음을 수행하여 애플리케이션을 실행합니다.

  1. F5 키를 선택하거나 실행 파일 위치 ImageListener\bin\Debug\ImageListener.exe로 이동하여 서비스를 실행합니다. 다음 단계를 수행하는 데 필요하므로 앱을 실행 상태로 둡니다.
  2. 이미지를 보려면 명령 프롬프트에서 주소를 복사하여 브라우저로 붙여 넣습니다.
  3. 완료되면 명령 프롬프트 창에서 Enter를 선택하여 앱을 닫습니다.

다음 단계

이제 Azure Relay 서비스를 사용하는 애플리케이션을 빌드했습니다. 자세한 정보는 다음 문서를 참조하세요.