بدء استخدام طلبات HTTP الاتصال المختلطة Relay في Java

في هذا التشغيل السريع، يمكنك إنشاء تطبيقات مرسل واستقبال Java التي ترسل الرسائل وتستقبلها باستخدام بروتوكول HTTP. تستخدم التطبيقات ميزة hybrid الاتصال ions في Azure Relay. للتعرف على Azure Relay بشكل عام، راجع Azure Relay.

في هذا التشغيل السريع، يمكنك اتخاذ الخطوات التالية:

  1. إنشاء مساحة اسم Relay باستخدام مدخل Microsoft Azure.
  2. إنشاء اتصال مختلط في مساحة الاسم هذه باستخدام مدخل Microsoft Azure.
  3. اكتب تطبيق وحدة تحكم خادم (وحدة استماع) لتلقي الرسائل.
  4. اكتب تطبيق وحدة تحكم العميل (المرسل) لإرسال الرسائل.
  5. تشغيل التطبيقات.

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

إنشاء مساحة اسم باستخدام مدخل Microsoft Azure

  1. قم بتسجيل الدخول إلى بوابة Azure.

  2. حدد كل الخدمات في القائمة اليسرى. حدد Integration، وابحث عن Relays، وحرك الماوس فوق Relays، ثم حدد Create.

    لقطة شاشة تعرض تحديد Relays -> الزر Create.

  3. في صفحة Create namespace ، اتبع الخطوات التالية:

    1. بالنسبة إلى Subscription، اختر اشتراك Azure لإنشاءnamespace.

    2. بالنسبة لـ "مجموعة الموارد"، اختر مجموعة موارد موجودة حيث توجد namespace، أو إنشاء مجموعة موارد جديدة.

    3. أدخل اسما لمساحة اسم الترحيل.

    4. حدد المنطقة التي يجب استضافة مساحة الاسم فيها.

    5. حدد مراجعة + إنشاء عند أسفل الصفحة.

      لقطة شاشة تعرض صفحة إنشاء مساحة الاسم.

    6. في صفحة مراجعة+ إنشاء حدد إنشاء.

    7. بعد بضع دقائق، سترى صفحة Relay لمساحة الاسم.

      لقطة شاشة تعرض الصفحة الرئيسية لمساحة اسم Relay.

الحصول على بيانات اعتماد الإدارة

  1. في صفحة Relay ، حدد Shared access policies في القائمة اليمنى. `

  2. في إطارShared access policies، حدد RootManageSharedAccessKey.

  3. في إطار سياسةSAS: RootManageSharedAccessKey، حدد زر نسخ سلسلة الاتصال الأساسية. يقوم هذا الإجراء بنسخ سلسلة الاتصال إلى الحافظة لاستخدامها لاحقاً. وقم بلصق هذه القيمة في المفكرة أو بعض المواقع المؤقتة الأخرى.

  4. كرر الخطوة السابقة، وهي نسخ قيمة المفتاح الأساسي ولصقها إلى موقع مؤقت للاستخدام لاحقاً.

    لقطة شاشة تعرض معلومات الاتصال لمساحة اسم Relay.

إنشاء اتصال مختلط باستخدام مدخل Microsoft Azure

في صفحة Relay لمساحة الاسم، اتبع هذه الخطوات لإنشاء اتصال مختلط.

  1. في القائمة اليسرى، ضمن Entities، حدد Hybrid الاتصال ions، ثم حدد + Hybrid الاتصال ion.

    لقطة شاشة تعرض صفحة hybrid الاتصال ions.

  2. في صفحة Create Hybrid الاتصال ion، أدخل اسما للاتصال المختلط، وحدد Create.

    لقطة شاشة تعرض صفحة إنشاء الاتصال المختلطة.

إنشاء تطبيق خادم (وحدة استماع)

للاستماع إلى الرسائل وتلقيها من Relay، اكتب تطبيق وحدة تحكم Java.

قم بإنشاء تطبيق Java

إذا قمت بتعطيل الخيار "يتطلب تخويل العميل" عند إنشاء الترحيل، يمكنك إرسال الطلبات إلى عنوان URL الاتصال المختلط مع أي مستعرض. للوصول إلى نقاط النهاية المحمية، تحتاج إلى إنشاء رمز مميز وتمريره في ServiceBusAuthorization العنوان، والذي يظهر هنا.

فيما يلي بنية مشروع Maven بسيطة وفئة Java توضح إرسال الطلبات إلى عنوان URL ل Hybrid الاتصال ions مع تخويل العميل باستخدام مكتبة Azure Relay.

إضافة حزمة الترحيل

تعديل ملف pom.xml في حزمة تطبيق maven لتضمين حزمة Azure Relay.

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-relay</artifactId>
    <version>0.0.6</version>
</dependency>

قم بتشغيل mvn dependency:copy-dependencies -DoutputDirectory=lib في مشروع mvn الخاص بك لإضافة ملف jar التبعية في دليل lib لمشروعك. يستورد جميع تبعيات حزمة azure-relay mvn. توفر هذه الحزمة وظائف لإنشاء معرفات موارد Relay الموحدة (URIs) والرموز المميزة.

كتابة بعض التعليمات البرمجية لإرسال الرسائل

  1. أضف ملفات jar للتبعية إلى ClassPath لملفك Listener.java .

    javac -cp lib/* src/main/java/com/example/listener/Listener.Java
    
  2. استيراد التبعيات إلى الفئة الخاصة بك Listener.java .

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    import com.microsoft.azure.relay.HybridConnectionListener;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.RelayedHttpListenerResponse;
    import com.microsoft.azure.relay.TokenProvider;
    
  3. أضف ما يلي constants إلى أعلى Listener.java الملف إلى دالة createConnectionString java لتفاصيل الاتصال المختلط.

    public static String createConnectionString(){
        StringBuilder connectionString = new StringBuilder();
        connectionString.append("Endpoint=sb://");
        connectionString.append("{namespace}");
        connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
        connectionString.append("{keyrule}");
        connectionString.append(";SharedAccessKey=");
        connectionString.append("{key}");
        connectionString.append(";EntityPath=");
        connectionString.append("{path}");
        return connectionString.toString();
    }
    

    استبدل العناصر النائبة بين قوسين بالقيم التي حصلت عليها عند إنشاء الاتصال المختلط.

    • namespace - مساحة اسم الترحيل. تأكد من استخدام اسم مساحة الاسم المؤهل بالكامل؛ على سبيل المثال، {namespace}.servicebus.windows.net.
    • path - اسم الاتصال المختلط.
    • keyrule - اسم مفتاح نهج الوصول المشترك، وهو RootManageSharedAccessKey بشكل افتراضي.
    • nst key - المفتاح الأساسي لمساحة الاسم التي حفظتها سابقا.
  4. أضف التعليمات البرمجية Listener.java التالية إلى الملف. يجب أن تبدو الدالة الرئيسية مثل التعليمات البرمجية التالية:

    public static void main( String[] args ) throws URISyntaxException
    {
        String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
        RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
        TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                    connectionParams.getSharedAccessKeyName(),
                    connectionParams.getSharedAccessKey());
        HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider);
    
        // The "context" object encapsulates both the incoming request and the outgoing response
        listener.setRequestHandler((context) -> {
            String receivedText = "";
            if (context.getRequest().getInputStream() != null) {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) {
                    StringBuilder builder = new StringBuilder();
                    String inputLine;
                    while ((inputLine = reader.readLine()) != null) {
                        builder.append(inputLine);
                    }
                    receivedText = builder.toString();
                } catch (IOException e) {
                    System.out.println(e.getMessage());
                }
            }
            System.out.println("requestHandler received " + receivedText);
    
            RelayedHttpListenerResponse response = context.getResponse();
            response.setStatusCode(202);
            response.setStatusDescription("OK");
    
            try {
                response.getOutputStream().write(("Echo: " + receivedText).getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            // The context MUST be closed for the message to be sent
            response.close();
        });
    
        listener.openAsync().join();
    
        Scanner in = new Scanner(System.in);
        System.out.println("Press ENTER to terminate this program.");
        in.nextLine();
    
        listener.close();
        in.close();
    }
    
    

    إليك الشكل الذي يجب أن يبدو عليه ملفك Listener.java :

    package com.example.listener;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    import com.microsoft.azure.relay.HybridConnectionListener;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.RelayedHttpListenerResponse;
    import com.microsoft.azure.relay.TokenProvider;
    
     public class Listener
     {
        public static String createConnectionString(){
            StringBuilder connectionString = new StringBuilder();
            connectionString.append("Endpoint=sb://");
            connectionString.append("{namespace}");
            connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
            connectionString.append("{keyrule}");
            connectionString.append(";SharedAccessKey=");
            connectionString.append("{key}");
            connectionString.append(";EntityPath=");
            connectionString.append("{path}");
            return connectionString.toString();
        }
    
        public static void main( String[] args ) throws URISyntaxException
        {
            String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
            RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
            TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                        connectionParams.getSharedAccessKeyName(),
                        connectionParams.getSharedAccessKey());
            HybridConnectionListener listener = new HybridConnectionListener(new URI(connectionParams.getEndpoint().toString() + connectionParams.getEntityPath()), tokenProvider);
    
            // The "context" object encapsulates both the incoming request and the outgoing response
            listener.setRequestHandler((context) -> {
                String receivedText = "";
                if (context.getRequest().getInputStream() != null) {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getRequest().getInputStream(), "UTF8"))) {
                        StringBuilder builder = new StringBuilder();
                        String inputLine;
                        while ((inputLine = reader.readLine()) != null) {
                            builder.append(inputLine);
                        }
                        receivedText = builder.toString();
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
                }
                System.out.println("requestHandler received " + receivedText);
    
                RelayedHttpListenerResponse response = context.getResponse();
                response.setStatusCode(202);
                response.setStatusDescription("OK");
    
                try {
                    response.getOutputStream().write(("Echo: " + receivedText).getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                // The context MUST be closed for the message to be sent
                response.close();
            });
    
            listener.openAsync().join();
    
            Scanner in = new Scanner(System.in);
            System.out.println("Press ENTER to terminate this program.");
            in.nextLine();
    
            listener.close();
            in.close();
        }
    }
    

إنشاء تطبيق عميل (مرسل)

لإرسال رسائل إلى Relay، يمكنك استخدام أي عميل HTTP، أو كتابة تطبيق وحدة تحكم Java.

قم بإنشاء تطبيق Java

إذا قمت بتعطيل الخيار "يتطلب تخويل العميل" عند إنشاء الترحيل، يمكنك إرسال الطلبات إلى عنوان URL الاتصال المختلط مع أي مستعرض. للوصول إلى نقاط النهاية المحمية، تحتاج إلى إنشاء رمز مميز وتمريره في ServiceBusAuthorization العنوان، والذي يظهر هنا.

فيما يلي بنية مشروع Maven بسيطة وفئة Java توضح إرسال الطلبات إلى عنوان URL ل Hybrid الاتصال ions مع تخويل العميل باستخدام مكتبة Azure Relay.

إضافة حزمة الترحيل

تعديل ملف pom.xml في حزمة تطبيق maven لتضمين حزمة Azure Relay.

<dependency>
	<groupId>com.microsoft.azure</groupId>
	<artifactId>azure-relay</artifactId>
	<version>0.0.6</version>
</dependency>

قم بتشغيل mvn dependency:copy-dependencies -DoutputDirectory=lib في مشروع mvn الخاص بك لإضافة ملف jar التبعية في دليل lib لمشروعك. كما أنه يستورد جميع تبعيات حزمة azure-relay mvn. توفر هذه الحزمة وظائف لإنشاء معرفات موارد Relay الموحدة (URIs) والرموز المميزة.

كتابة بعض التعليمات البرمجية لإرسال الرسائل

  1. أضف ملفات jar للتبعية إلى ClassPath لملفك Sender.java .

    javac -cp lib/* src/main/java/com/example/sender/Sender.Java
    
  2. استيراد التبعيات إلى الفئة الخاصة بك Sender.java .

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Duration;
    import java.util.Scanner;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.TokenProvider;
    
  3. أضف ما يلي constants إلى أعلى Sender.java الملف إلى دالة createConnectionString java لتفاصيل الاتصال المختلط.

    public static String createConnectionString(){
        StringBuilder connectionString = new StringBuilder();
        connectionString.append("Endpoint=sb://");
        connectionString.append("{namespace}");
        connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
        connectionString.append("{keyrule}");
        connectionString.append(";SharedAccessKey=");
        connectionString.append("{key}");
        connectionString.append(";EntityPath=");
        connectionString.append("{path}");
        return connectionString.toString();
    }
    

    استبدل العناصر النائبة بين قوسين بالقيم التي حصلت عليها عند إنشاء الاتصال المختلط.

    • namespace - مساحة اسم الترحيل. تأكد من استخدام اسم مساحة الاسم المؤهل بالكامل؛ على سبيل المثال، {namespace}.servicebus.windows.net.
    • path - اسم الاتصال المختلط.
    • keyrule - اسم مفتاح نهج الوصول المشترك، وهو RootManageSharedAccessKey بشكل افتراضي.
    • nst key - المفتاح الأساسي لمساحة الاسم التي حفظتها سابقا.
  4. أضف التعليمات البرمجية Sender.java التالية إلى الملف. يجب أن تبدو الدالة الرئيسية مثل التعليمات البرمجية التالية.

    public static void main(String[] args) throws IOException {
        String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
        if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){
            System.err.println("Connection string is null or empty. Please check your createConnectionString method.");
            return;
        }
        RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
        TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                connectionParams.getSharedAccessKeyName(), 
                connectionParams.getSharedAccessKey());
        URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath());
        String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken();
        Scanner in = new Scanner(System.in);
        while (true) {
            System.out.println("Press ENTER to terminate this program.");
            String message = in.nextLine();
            int value = System.in.read();
            if (value == '\n' || value == '\r') {
                System.out.println("Terminating the program...");
                break;}
            // Starting a HTTP connection to the listener
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // Sending an HTTP request to the listener
            // To send a message body, use POST
            conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST");
            conn.setRequestProperty("ServiceBusAuthorization", tokenString);
            conn.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
            out.write(message, 0, message.length());
            out.flush();
            out.close();
            // Reading the HTTP response
            String inputLine;
            BufferedReader reader = null;
            StringBuilder responseBuilder = new StringBuilder();
            try {
                InputStream inputStream = conn.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));
                System.out.println("status code: " + conn.getResponseCode());
                while ((inputLine = reader.readLine()) != null) {
                    responseBuilder.append(inputLine);
                }
                System.out.println("received back " + responseBuilder.toString());
            } catch (IOException e) {
                System.out.println("The listener is offline or could not be reached.");
                break;
            } finally {
                if (reader != null) {
                    reader.close();
                }
            }
        }
        in.close();
    }
    
    static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException {
        StringBuilder urlBuilder = new StringBuilder(endpoint + entity);
    
        // For HTTP connections, the scheme must be https://
        int schemeIndex = urlBuilder.indexOf("://");
        if (schemeIndex < 0) {
            throw new IllegalArgumentException("Invalid scheme from the given endpoint.");
        }
        urlBuilder.replace(0, schemeIndex, "https");
        return new URL(urlBuilder.toString());
    }
    

    إليك الشكل الذي يجب أن يبدو عليه ملفك Sender.java :

    package com.example.sender;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.time.Duration;
    import java.util.Scanner;
    import com.microsoft.azure.relay.RelayConnectionStringBuilder;
    import com.microsoft.azure.relay.TokenProvider;
    
    public class Sender
    {
        public static String createConnectionString(){
            StringBuilder connectionString = new StringBuilder();
            connectionString.append("Endpoint=sb://");
            connectionString.append("{namespace}");
            connectionString.append(".servicebus.windows.net/;SharedAccessKeyName=");
            connectionString.append("{keyrule}");
            connectionString.append(";SharedAccessKey=");
            connectionString.append("{key}");
            connectionString.append(";EntityPath=");
            connectionString.append("{path}");
            return connectionString.toString();
            }
        public static void main(String[] args) throws IOException {
            String CONNECTION_STRING_ENV_VARIABLE_NAME = createConnectionString();
            if (CONNECTION_STRING_ENV_VARIABLE_NAME == null || CONNECTION_STRING_ENV_VARIABLE_NAME.isEmpty()){
                System.err.println("Connection string is null or empty. Please check your createConnectionString method.");
                return;
            }
            RelayConnectionStringBuilder connectionParams = new RelayConnectionStringBuilder(CONNECTION_STRING_ENV_VARIABLE_NAME);
            TokenProvider tokenProvider = TokenProvider.createSharedAccessSignatureTokenProvider(
                    connectionParams.getSharedAccessKeyName(), 
                    connectionParams.getSharedAccessKey());
            URL url = buildHttpConnectionURL(connectionParams.getEndpoint().toString(), connectionParams.getEntityPath());
            String tokenString = tokenProvider.getTokenAsync(url.toString(), Duration.ofHours(1)).join().getToken();
            Scanner in = new Scanner(System.in);
            while (true) {
                System.out.println("Press ENTER to terminate this program.");
                String message = in.nextLine();
                int value = System.in.read();
                if (value == '\n' || value == '\r') {
                    System.out.println("Terminating the program...");
                    break;}
                // Starting a HTTP connection to the listener
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                // Sending an HTTP request to the listener
                // To send a message body, use POST
                conn.setRequestMethod((message == null || message.length() == 0) ? "GET" : "POST");
                conn.setRequestProperty("ServiceBusAuthorization", tokenString);
                conn.setDoOutput(true);
                OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
                out.write(message, 0, message.length());
                out.flush();
                out.close();
                // Reading the HTTP response
                String inputLine;
                BufferedReader reader = null;
                StringBuilder responseBuilder = new StringBuilder();
                try {
                    InputStream inputStream = conn.getInputStream();
                    reader = new BufferedReader(new InputStreamReader(inputStream));
                    System.out.println("status code: " + conn.getResponseCode());
                    while ((inputLine = reader.readLine()) != null) {
                        responseBuilder.append(inputLine);
                    }
                    System.out.println("received back " + responseBuilder.toString());
                } catch (IOException e) {
                    System.out.println("The listener is offline or could not be reached.");
                    break;
                } finally {
                    if (reader != null) {
                        reader.close();
                    }
                }
            }
            in.close();
        }
    
        static URL buildHttpConnectionURL(String endpoint, String entity) throws MalformedURLException {
            StringBuilder urlBuilder = new StringBuilder(endpoint + entity);
    
            // For HTTP connections, the scheme must be https://
            int schemeIndex = urlBuilder.indexOf("://");
            if (schemeIndex < 0) {
                throw new IllegalArgumentException("Invalid scheme from the given endpoint.");
            }
            urlBuilder.replace(0, schemeIndex, "https");
            return new URL(urlBuilder.toString());
        }
    }
    

تشغيل التطبيقات

  1. تشغيل تطبيق الخادم: من موجه أوامر Java أو نوع java -cp <jar_dependency_path> com.example.listener.Listener.javaالتطبيق .
  2. تشغيل تطبيق العميل: من موجه أوامر Java أو نوع java -cp <jar_dependency_path> com.example.sender.Sender.javaالتطبيق ، وأدخل بعض النص.
  3. تأكد من أن وحدة تحكم تطبيق الخادم إخراج النص الذي تم إدخاله في تطبيق العميل.

تهانينا، لقد أنشأت تطبيق hybrid الاتصال ions من طرف إلى طرف باستخدام Java!

الخطوات التالية

في هذا التشغيل السريع، قمت بإنشاء تطبيقات عميل وخادم Java التي استخدمت HTTP لإرسال الرسائل وتلقيها. تدعم ميزة الاتصال المختلطة في Azure Relay أيضا استخدام WebSockets لإرسال الرسائل وتلقيها. لمعرفة كيفية استخدام WebSockets مع azure Relay Hybrid الاتصال ions، راجع التشغيل السريع WebSockets.

في هذا التشغيل السريع، استخدمت Java لإنشاء تطبيقات العميل والخادم. لمعرفة كيفية كتابة تطبيقات العميل والخادم باستخدام .NET Framework، راجع التشغيل السريع ل .NET WebSockets أو التشغيل السريع ل .NET HTTP.