البرنامج التعليمي: البرنامج التعليمي حول Azure WCF Relay REST

يصف هذا البرنامج التعليمي كيفية إنشاء تطبيق مضيف Azure Relay يعرض واجهة تستند إلى REST. يتيح REST لعميل ويب، مثل مستعرض ويب، الوصول إلى واجهات برمجة التطبيقات ناقل الخدمة من خلال طلبات HTTP.

يستخدم البرنامج التعليمي نموذج البرمجة Windows Communication Foundation (WCF) REST لبناء خدمة REST على Azure Relay. لمزيد من المعلومات، راجع WCF REST Programming Model وDesigning and Implementing Services.

ستنفذ بالمهام التالية في هذا البرنامج التعليمي:

  • قم بتثبيت المتطلبات الأساسية لهذا البرنامج التعليمي.
  • إنشاء مساحة اسم Relay.
  • تعريف عقد خدمة WCF المستندة إلى REST.
  • تنفيذ عقد WCF المستندة إلى REST.
  • استضافة خدمة WCF المستندة إلى REST وتشغيلها.
  • تشغيل الخدمة واختبارها.

المتطلبات الأساسية

لاستكمال هذا البرنامج التعليمي، ستحتاج إلى المتطلبات الأساسية التالية:

إنشاء مساحة اسم Relay

لبدء استخدام ميزات الترحيل في Azure، يجب أولاً إنشاء مساحة اسم خدمة. توفر مساحة الاسم حاوية تحديد نطاق لمخاطبة موارد Azure داخل تطبيقك. اتبع الإرشادات هنا لإنشاء مساحة اسم Relay.

تعريف عقد خدمة WCF المستندة إلى REST اللازم استخدامه مع Azure Relay

عند إنشاء خدمة بنمط WCF REST، عليك تعريف العقد. يحدد العقد العمليات التي يدعمها المضيف. تشبه عملية الخدمة أسلوب خدمة ويب. تعريف عقد من خلال واجهة C++‎، أو C#‎، أو Visual Basic. يتوافق كل أسلوب في الواجهة مع عملية خدمة معينة. قم بتطبيق السمة ServiceContractAttribute على كل واجهة، وتطبيق السمة OperationContractAttribute على كل عملية.

تلميح

إذا لم يكن أحد الأساليب في واجهة يحتوي على ServiceContractAttribute ولا يحتوي على OperationContractAttribute، فلا يتم كشف هذا الأسلوب. تظهر التعليمات البرمجية المستخدمة لهذه المهام في المثال التالي للإجراء.

الفرق الأساسي بين عقد WCF وعقد بنمط REST هو إضافة خاصية إلى OperationContractAttribute: وهي WebGetAttribute. تمكّنك هذه الخاصية من تعيين أسلوب في الواجهة إلى أسلوب على الجانب الآخر من الواجهة. يستخدم هذا المثال السمة WebGetAttribute لربط أسلوب بـHTTP GET. يمكّن هذا الأسلوب «ناقل الخدمة» لاسترداد الأوامر المرسلة إلى الواجهة وفهمها بدقة.

لإنشاء عقد مع واجهة

  1. ابدأ تشغيل Microsoft Visual Studio كمسؤول. للقيام بذلك، انقر بزر الماوس الأيمن فوق التعليمة البرمجية لبرنامج Visual Studio، وحدد Run as administrator.

  2. في Visual Studio، حدد Create a new project.

  3. فيCreate a new project، اختر Console App (.NET Framework) لـ C#‎ وحدد Next.

  4. عيّن للمشروع الاسم ImageListener. استخدم Location الافتراضي، ثم حدد Create.

    لمشروع C#‎، ينشئ Visual Studio الملف Program.cs. تحتوي هذه الفئة على أسلوب Main() فارغ، ومطلوب لمشروع تطبيق وحدة تحكم الإنشاء بشكل صحيح.

  5. في Solution Explorer، انقر زر الماوس الأيمن على المشروع ImageListener، ثم حدد Manage NuGet Packages.

  6. حدد Browse، ثم ابحث عن واختر WindowsAzure.ServiceBus. حدد Install، واقبل شروط الاستخدام.

    تضيف هذه الخطوة مراجع إلى «ناقل الخدمة» وSystem.ServiceModel.dll. تضيف هذه الحزمة تلقائيًا مراجع إلى مكتبات «ناقل الخدمة» وSystem.ServiceModel لـWCF.

  7. أضف مرجعًا إلى System.ServiceModel.Web.dll إلى المشروع بشكل صريح. انقر بزر الماوس الأيمن على Solution Explorer على References ضمن مجلد المشاريع هذا، وحدد Add Reference.

  8. في Add Reference، حدد Framework وأدخِل System.ServiceModel.Web في Search. حدد خانة الاختيار System.ServiceModel.Web ، ثم حدد OK.

بعد ذلك، قم بإجراء تغييرات التعليمات البرمجية التالية إلى المشروع:

  1. أضف عبارات using التالية في الجزء العلوي من ملف Program.cs.

    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;
    using System.IO;
    
    • يُعد System.ServiceModel مساحة الاسم التي تتيح الوصول البرمجي إلى الميزات الأساسية لـ WCF. يستخدم WCF Relay العديد من الكائنات وسمات 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
    {
    }
    

    تختلف قيمة مساحة الاسم عن مساحة الاسم التي تستخدمها في نطاق التعليمات البرمجية. تُعد قيمة مساحة الاسم معرفًا فريدًا لهذا العقد، ويجب أن تحتوي على معلومات الإصدار. لمزيد من المعلومات، راجع Service Versioning. يمنع تحديد مساحة الاسم بشكل صريح قيمة مساحة الاسم الافتراضية من إضافتها إلى اسم العقد.

  4. ضمن الواجهة IImageContract، قم بتعريف أسلوب العملية الفردية التي يكشفها العقد IImageContract في الواجهة، وتطبيق السمة 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، أعلن قناة ترث من كل من الواجهتين IImageContract وIClientChannel.

    public interface IImageChannel : IImageContract, IClientChannel { }
    

    تُعد القناة كائن WCF التي من خلاله تمرر الخدمة والعميل المعلومات إلى بعضهما البعض. لاحقًا، ستتمكن من إنشاء القناة في تطبيق المضيف لديك. بعد ذلك يستخدم Azure Relay هذه القناة لتمرير طلبات HTTP GET من المستعرض إلى تنفيذ GetImage لديك. يستخدم الترحيل أيضًا القناة لأخذ قيمة الإرجاع GetImage وترجمتها إلى HTTP GETRESPONSE لمستعرض العميل.

  7. حدد Build>Build Solution لتأكيد دقة عملك حتى الآن.

مثال يعرف عقد WCF Relay

تعرض التعليمات البرمجية التالية واجهة أساسية تعرف عقد WCF Relay.

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)
        {
        }
    }
}

تنفيذ عقد خدمة WCF المستند إلى REST

لإنشاء خدمة WCF Relay بنمط REST، أنشئ العقد أولاً باستخدام واجهة. الخطوة التالية هي تنفيذ الواجهة. يتضمن هذا الإجراء إنشاء فئة تسمى ImageService تقوم بتنفيذ الواجهة IImageContract المعرفة من قبل المستخدم. بعد تنفيذ العقد، يمكنك تكوين الواجهة باستخدام الملف App.config. يحتوي ملف التكوين على المعلومات الضرورية للتطبيق. تتضمن هذه المعلومات اسم الخدمة، واسم العقد، ونوع البروتوكول المستخدم للاتصال بخدمة الترحيل. تظهر التعليمات البرمجية المستخدمة لهذه المهام في المثال التالي للإجراء.

كما هو الحال مع الخطوات السابقة، هناك فرق ضئيل بين تنفيذ عقد بنمط REST وعقد WCF Relay.

لتنفيذ عقد ناقل الخدمة بنمط REST

  1. أنشئ فئة جديدة تسمي ImageService مباشرةً بعد تعريف الواجهة IImageContract. فئة ImageService تنفذ واجهةIImageContract.

    class ImageService : IImageContract
    {
    }
    

    بالمثل إلى تنفيذات الواجهات الأخرى، يمكنك تنفيذ التعريف في ملف مختلف. ومع ذلك، ولهذا البرنامج التعليمي، يظهر التنفيذ في الملف نفسه كتعريف الواجهة والأسلوب Main().

  2. قم بتطبيق السمة ServiceBehaviorAttribute إلى الفئة IImageService للإشارة إلى أن الفئة تنفيذ لعقد WCF.

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

    كما ذُكر سابقًا، مساحة الاسم هذه ليست مساحة اسم تقليدية. إنها جزء من بنية WCF التي تحدد العقد. لمزيد من المعلومات، راجع Data Contract Names.

  3. أضف صورة ‎.jpg إلى مشروعك. يُعد هذا الملف صورة تعرضها الخدمة في المستعرض المتلقي.

    1. انقر بزر الماوس الأيمن على المشروع، وحدد Add.
    2. ثم حدد Existing Item.
    3. استخدم Add Existing Item للاستعراض إلى ملف ‎.jpg المناسب، ثم حدد Add. عند إضافة الملف، حدد All Files من القائمة المنسدلة بجوار File name.

    يفترض بقية هذا البرنامج التعليمي أن اسم الصورة هو image.jpg. إذا كان لديك ملف مختلف، فعليك إعادة تسمية الصورة، أو تغيير التعليمات البرمجية للتعويض.

  4. للتأكد من أن الخدمة قيد التشغيل بإمكانها العثور على ملف الصورة، في Solution Explorer، انقر بزر الماوس الأيمن على ملف الصورة، ثم اختر Properties. في Properties، عيّن القيمة Copy to Output Directory إلى Copy if newer.

  5. استخدم الإجراء في To create a contract with an interface لإضافة مرجع إلى تجميع 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. مباشرةً بعد التعليمات البرمجية السابقة، أضف الأسلوب GetImage التالي في الفئة ImageService لإرجاع رسالة HTTP التي تحتوي على الصورة.

    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 لاسترداد الصورة وتحضيرها للبث إلى المستعرض. يبدأ موضع الدفق عند الصفر، ويعلن محتوى الدفق بتنسيق ‎.jpg، ويدفق المعلومات.

  9. حدد Build>Build Solution.

لتعريف التكوين لتشغيل خدمة الويب على ناقل الخدمة

  1. في Solution Explorer، انقر نقرًا مزدوجًا على App.config لفتح الملف في محرر Visual Studio.

    يتضمن ملف App.config اسم الخدمة، ونقطة النهاية، والربط. تُعد نقطة النهاية الموقع الذي يكشفه Azure Relay للعملاء والمضيفين للاتصال مع بعضهم البعض. الربط هو نوع البروتوكول المستخدم للتواصل. الفرق الرئيسي هنا هو أن نقطة نهاية الخدمة المكونة تشير إلى ربط WebHttpRelayBinding .

  2. يُعد عنصر XML <system.serviceModel> عنصر WCF يعرف خدمة واحدة أو أكثر. هنا، يتم استخدامه لتعريف اسم الخدمة ونقطة النهاية. في نهاية العنصر <system.serviceModel>، ولكن ضمن <system.serviceModel> كذلك، أضف عنصر <bindings> يحتوي على المحتوى التالي:

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

    يعرف هذا المحتوى الارتباطات المستخدمة في التطبيق. يمكنك تعريف روابط متعددة، ولكن بالنسبة لهذا البرنامج التعليمي، ستتمكن من تعريف واحد فقط.

    تعرف التعليمات البرمجية السابقة ربط WebHttpRelayBinding في WCF Relay مع تعيين relayClientAuthenticationType إلى None. يشير هذا الإعداد إلى أن نقطة النهاية التي تستخدم هذا الربط لا تتطلب بيانات اعتماد عميل.

  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). للحصول على مفتاح SAS من مدخل Azure، راجع Get management credentials.

    <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. حدد Build>Build Solution لإنشاء الحل بأكمله.

مثال ينفذ عقد خدمة WCF المستندة إلى REST

تعرض التعليمات البرمجية التالية تنفيذ العقد والخدمة لخدمة تستند إلى REST قيد التشغيل على «ناقل الخدمة» باستخدام الربط WebHttpRelayBinding.

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>

استضافة خدمة WCF المستندة إلى REST لاستخدام Azure Relay

يصف هذا القسم كيفية تشغيل خدمة ويب باستخدام تطبيق وحدة تحكم مع WCF Relay. يظهر سرد كامل للتعليمات البرمجية المكتوبة في هذا القسم في المثال التالي للإجراء.

لإنشاء عنوان أساسي للخدمة

  1. في إعلان الدالة Main()، أنشئ متغيرًا لتخزين مساحة الاسم لمشروعك. تأكد من استبدال yourNamespace باسم مساحة اسم Relay التي قمت بإنشائها مسبقًا.

    string serviceNamespace = "yourNamespace";
    

    يستخدم «ناقل الخدمة» اسم مساحة الاسم لديك لإنشاء 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، راجع المقالات التالية لمعرفة المزيد: