共用方式為


在 Java 中開始使用轉送混合式 連線 HTTP 要求

在本快速入門中,您會使用 HTTP 通訊協定建立 Java 傳送者和接收者應用程式,以傳送和接收訊息。 應用程式會使用 Azure 轉送的混合式 連線 功能。 若要瞭解 Azure 轉寄一般,請參閱 Azure 轉寄

在本快速入門中,您會採取下列步驟:

  1. 使用 Azure 入口網站 建立轉寄命名空間。
  2. 使用 Azure 入口網站,在該命名空間中建立混合式連線。
  3. 撰寫伺服器(接聽程式)控制台應用程式以接收訊息。
  4. 撰寫用戶端 (sender) 主控台應用程式以傳送訊息。
  5. 執行應用程式。

必要條件

使用 Azure 入口網站 建立命名空間

  1. 登入 Azure 入口網站

  2. 選取左側功能表上的 [所有服務]。 依序選取 [整合]、搜尋 [轉寄]、將滑鼠移至 [轉寄] 上方,然後選取 [建立]。

    顯示選取 [轉寄 -> 建立] 按鈕的螢幕快照。

  3. 在 [ 建立命名空間] 頁面上,遵循下列步驟:

    1. 選擇要在其中建立命名空間的 Azure 訂用帳戶。

    2. 針對 [ 資源群組],選擇要放置命名空間的現有資源群組,或建立新的資源群組。

    3. 輸入轉寄命名空間的名稱。

    4. 選取您的命名空間應該裝載所在的區域。

    5. 選取頁面底部的 [檢閱 + 建立] 。

      顯示 [建立命名空間] 頁面的螢幕快照。

    6. 在 [檢閱 + 建立] 頁面上,選取 [建立]

    7. 幾分鐘后,您會看到 命名空間的 [轉寄 ] 頁面。

      顯示轉接命名空間首頁的螢幕快照。

取得管理認證

  1. 在 [ 轉寄 ] 頁面上,選取 左側功能表上的 [共用存取原則 ]。 `

  2. 在 [共用存取原則] 頁面上,選取 [RootManageSharedAccessKey]

  3. 在 [SAS 原則:RootManageSharedAccessKey] 下,選取 [主要 連線 ion 字串] 旁的 [複製] 按鈕。 此動作會將 連接字串 複製到剪貼簿以供稍後使用。 將此值貼到記事本或一些其他暫存位置。

  4. 重複上述步驟,將 [主要密鑰] 的值複製並貼到暫存位置,以供日後使用。

    顯示轉接命名空間之連線資訊的螢幕快照。

使用 Azure 入口網站 建立混合式連線

在命名空間的 [ 轉送 ] 頁面上,遵循下列步驟來建立混合式連線。

  1. 在左側功能表上的 [實體] 底下,選取 [混合式 連線 集],然後選取 [+ 混合式 連線。

    顯示混合式 連線 頁面的螢幕快照。

  2. 在 [建立混合式 連線 ion] 頁面上,輸入混合式連線的名稱,然後選取 [建立]。

    顯示 [建立混合式 連線] 頁面的螢幕快照。

建立伺服器應用程式 (接聽程式)

若要接聽和接收來自轉寄的訊息,請撰寫 Java 控制台應用程式。

建立 Java 應用程式

如果您在建立轉送時停用 [需要用戶端授權] 選項,您可以使用任何瀏覽器將要求傳送至混合式 連線 IONS URL。 若要存取受保護的端點,您必須在標頭中 ServiceBusAuthorization 建立並傳遞令牌,如下所示。

以下是簡單的 Maven 項目結構和 Java 類別,示範如何使用 Azure 轉送連結庫將要求傳送至混合式 連線 URL。

新增轉寄套件

修改 maven 應用程式套件中的pom.xml檔案,以包含 Azure 轉寄套件。

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

在mvn項目中執行 mvn dependency:copy-dependencies -DoutputDirectory=lib ,以在專案的 lib 目錄中新增相依性 jar 檔案。 它會匯入mvn套件的所有相依性 azure-relay 。 此套件提供函式來建構轉寄統一資源識別碼 (URI) 和令牌。

撰寫一些程式代碼來傳送訊息

  1. 將相依性 jar 檔案新增至檔案 Listener.java 的 ClassPath。

    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 檔案。 main 函式看起來應該像下列程式代碼:

    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();
        }
    }
    

建立用戶端應用程式 (寄件者)

若要將訊息傳送至轉送,您可以使用任何 HTTP 用戶端,或撰寫 Java 控制台應用程式。

建立 Java 應用程式

如果您在建立轉送時停用 [需要用戶端授權] 選項,您可以使用任何瀏覽器,將要求傳送至混合式 連線 IONS URL。 若要存取受保護的端點,您必須在標頭中 ServiceBusAuthorization 建立並傳遞令牌,如下所示。

以下是簡單的 Maven 項目結構和 Java 類別,示範如何使用 Azure 轉送連結庫將要求傳送至混合式 連線 URL。

新增轉寄套件

修改 maven 應用程式套件中的pom.xml檔案,以包含 Azure 轉寄套件。

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

在mvn項目中執行 mvn dependency:copy-dependencies -DoutputDirectory=lib ,以在專案的 lib 目錄中新增相依性 jar 檔案。 它也會匯入mvn套件的所有相依性 azure-relay 。 此套件提供函式來建構轉寄統一資源識別碼 (URI) 和令牌。

撰寫一些程式代碼來傳送訊息

  1. 將相依性 jar 檔案新增至檔案 Sender.java 的 ClassPath。

    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 檔案。 main 函式看起來應該像下列程序代碼。

    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. 確定伺服器應用程式主控台會輸出用戶端應用程式中輸入的文字。

恭喜您,您已使用 Java 建立端對端混合式 連線 ions 應用程式!

下一步

在本快速入門中,您已建立使用 HTTP 來傳送和接收訊息的 Java 用戶端和伺服器應用程式。 Azure 轉送的混合式 連線 功能也支援使用 WebSocket 來傳送和接收訊息。 若要瞭解如何搭配 Azure 轉送混合式 連線 使用 WebSocket,請參閱 WebSockets 快速入門

在本快速入門中,您已使用 Java 來建立用戶端和伺服器應用程式。 若要瞭解如何使用 .NET Framework 撰寫用戶端和伺服器應用程式,請參閱 .NET WebSockets 快速入門.NET HTTP 快速入門