共用方式為


在您自己的伺服器間強制透過 Proxy 處理呼叫流量

在本教學課程中,您將了解如何在您自己的伺服器間透過 Proxy 處理 Azure 通訊服務呼叫流量。

在某些情況下,讓所有用戶端流量都透過 Proxy 傳送至您可控制的伺服器,可能有其效用。 SDK 進行初始化時,您可以針對流量要路由傳送到的伺服器提供詳細資料。 啟用後,所有媒體流量 (音訊/視訊/螢幕畫面分享) 都會通過提供的 TURN 伺服器,而不是 Azure 通訊服務預設值。

在本教學課程中,您會了解如何:

  • 設定 TURN 伺服器。
  • 設定訊號 Proxy 伺服器。

必要條件

Proxy 功能通常從公開的 Azure 通訊服務呼叫 SDK 1.25.1 版開始提供。 嘗試使用這項功能時,請務必使用此 SDK 或更新版本的 SDK。 本教學課程使用呼叫 SDK 1.13.0-beta.1 的版本,在該版本中,此功能首次可用於公開預覽。

對媒體流量進行 Proxy 呼叫

以下幾節說明如何對媒體流量進行 Proxy 呼叫。

什麼是 TURN 伺服器?

很多時候,要在兩個同儕節點之間建立網路連線並不容易。 基於下列原因,直接連線可能無法運作:

  • 防火牆有嚴格的規則。
  • 同儕節點位於私人網路後方。
  • 電腦執行於網路位址轉譯 (NAT) 環境中。

若要解決這些網路連線問題,您可以使用採用 Traversal Using Relay NAT (TURN) 通訊協定來轉送網路流量的伺服器。 NAT 的工作階段周遊公用程式 (STUN) 和 TURN 伺服器是轉送伺服器。

向 SDK 提供您的 TURN 伺服器詳細資料

若要提供 TURN 伺服器的詳細資料,您必須傳遞在初始化 CallClient 時要將哪個 TURN 伺服器作為 CallClientOptions 一部分的詳細資料。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Web SDK,以取得如何設定語音和視訊的快速入門。

import { CallClient } from '@azure/communication-calling'; 

const myTurn1 = {
    urls: [
        'turn:turn.azure.com:3478?transport=udp',
        'turn:turn1.azure.com:3478?transport=udp',
    ],
    username: 'turnserver1username',
    credential: 'turnserver1credentialorpass'
};

const myTurn2 = {
    urls: [
        'turn:20.202.255.255:3478',
        'turn:20.202.255.255:3478?transport=tcp',
    ],
    username: 'turnserver2username',
    credential: 'turnserver2credentialorpass'
};

// While you are creating an instance of the CallClient (the entry point of the SDK):
const callClient = new CallClient({
    networkConfiguration: {
        turn: {
            iceServers: [
                myTurn1,
                myTurn2
            ]
        }
    }
});




// ...continue normally with your SDK setup and usage.

重要

如果您在初始化 CallClient 時提供了 TURN 伺服器詳細資料,則所有媒體流量都只會流經這些 TURN 伺服器。 在嘗試在同儕節點之間建立連線時,將不會考量在您建立呼叫時通常會產生的任何其他 ICE 候選項目。 這表示只會考量 relay 候選項目。 若要深入了解不同類型的 ICE 候選項目,請參閱 RTCIceCandidate:type 屬性

如果 ?transport 查詢參數未作為 TURN URL 的一部分,或不是 udptcptls 值之一,則預設行為將是 UDP。

如果提供的 URL 無效,或沒有 turn:turns:stun: 結構描述,CallClient 初始化就會失敗,並據以擲回錯誤。 擲回的錯誤訊息應可協助您排解您遇到的問題。

如需 CallClientOptions 物件的 API 參考及其中的 networkConfiguration 屬性,請參閱 CallClientOptions

在 Azure 中設定 TURN 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器。 若要部署 TURN 伺服器,請使用 coturn。 coturn 是適用於 VoIP 和 WebRTC 的 TURN 和 STUN 伺服器的免費開放原始碼實作。

設定 TURN 伺服器之後,您可以使用 WebRTC Trickle ICE 網頁上的指示加以測試。

透過 Proxy 處理訊號流量

若要提供 Proxy 伺服器的 URL,您必須在初始化 CallClient 時將其傳入作為 CallClientOptions 的一部分。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Web SDK,以取得如何設定語音和視訊的快速入門。

import { CallClient } from '@azure/communication-calling'; 

// While you are creating an instance of the CallClient (the entry point of the SDK):
const callClient = new CallClient({
    networkConfiguration: {
        proxy: {
            url: 'https://myproxyserver.com'
        }
    }
});

// ...continue normally with your SDK setup and usage.

注意

如果提供的 Proxy URL 是無效的 URL,CallClient 初始化就會失敗,並據以擲回錯誤。 擲回的錯誤訊息可協助您排解您遇到的問題。

如需 CallClientOptions 物件的 API 參考及其中的 networkConfiguration 屬性,請參閱 CallClientOptions

在 Express.js 中設定訊號 Proxy 中介軟體

您也可以在 Express.js 伺服器設定中建立 Proxy 中介軟體,藉此使用 http-proxy-middleware npm 套件來重新導向所有 URL。 該套件中的 createProxyMiddleware 函式應會涵蓋簡單的重新導向 Proxy 設定所需的功能。 以下是其使用範例,說明 SDK 為了讓所有 URL 如預期運作所需的一些 SDK 選項設定:

const proxyRouter = (req) => {
    // Your router function if you don't intend to set up a direct target

    // An example:
    if (!req.originalUrl && !req.url) {
        return '';
    }

    const incomingUrl = req.originalUrl || req.url;
    if (incomingUrl.includes('/proxy')) {
        return 'https://microsoft.com/forwarder/';
    }
    
    return incomingUrl;
}

const myProxyMiddleware = createProxyMiddleware({
    target: 'https://microsoft.com', // This will be ignored if a router function is provided, but createProxyMiddleware still requires this to be passed in (see its official docs on the npm page for the most recent changes)
    router: proxyRouter,
    changeOrigin: true,
    secure: false, // If you have proper SSL setup, set this accordingly
    followRedirects: true,
    ignorePath: true,
    ws: true,
    logLevel: 'debug'
});

// And finally pass in your proxy middleware to your express app depending on your URL/host setup
app.use('/proxy', myProxyMiddleware);

提示

如果發生 SSL 問題,請參閱 cors 套件。

在 Azure 上設定訊號 Proxy 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器,並於其上部署 NGINX 伺服器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器

以下是可供您用作範例的 NGINX 設定:

events {
    multi_accept       on;
    worker_connections 65535;
}
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    map $request_method $access_control_header {
        OPTIONS '*';
    }
    server {
        listen <port_you_want_listen_on> ssl;
        ssl_certificate     <path_to_your_ssl_cert>;
        ssl_certificate_key <path_to_your_ssl_key>;
        location ~* ^/(.*?\.(com|net)(?::[\d]+)?)/(.*)$ {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin '*' always;
                add_header Access-Control-Allow-Credentials 'true' always;
                add_header Access-Control-Allow-Headers '*' always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type 'text/plain';
                add_header Content-Length 0;
                return 204;
            }
            resolver 1.1.1.1;
            set $ups_host $1;
            set $r_uri $3;
            rewrite ^/.*$ /$r_uri break;
            proxy_set_header Host $ups_host;
            proxy_ssl_server_name on;
            proxy_ssl_protocols TLSv1.2;
            proxy_ssl_ciphers DEFAULT;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass_request_headers on;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Proxy "";
            proxy_set_header Access-Control-Allow-Origin $access_control_header;
            proxy_pass https://$ups_host;
            proxy_redirect https://$ups_host https://$host/$ups_host;
            proxy_intercept_errors on;
            error_page 301 302 307 = @process_redirect;
            error_page 400 405 = @process_error_response;
        }
        location @process_redirect {
            set $saved_redirect_location '$upstream_http_location';
            resolver 1.1.1.1;
            proxy_pass $saved_redirect_location;
            add_header X-DBUG-MSG "301" always;
        }
        location @process_error_response {
            add_header Access-Control-Allow-Origin * always;
        }
    }
}

Proxy 功能適用於 Teams 身分識別和 Azure 通訊服務 Teams 互通性動作。

對媒體流量進行 Proxy 呼叫

以下幾節說明如何對媒體流量進行 Proxy 呼叫。

什麼是 TURN 伺服器?

很多時候,要在兩個同儕節點之間建立網路連線並不容易。 基於下列原因,直接連線可能無法運作:

  • 防火牆有嚴格的規則。
  • 同儕節點位於私人網路後方。
  • 電腦執行於網路位址轉譯 (NAT) 環境中。

若要解決這些網路連線問題,您可以使用採用 Traversal Using Relay NAT (TURN) 通訊協定來轉送網路流量的伺服器。 NAT 的工作階段周遊公用程式 (STUN) 和 TURN 伺服器是轉送伺服器。

使用 SDK 提供您的 TURN 伺服器詳細資料

若要提供 TURN 伺服器的詳細資料,您必須傳遞在初始化 CallClient 時要將哪個 TURN 伺服器作為 CallClientOptions 一部分的詳細資料。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 iOS SDK,以取得如何設定語音和視訊的快速入門。

let callClientOptions = new CallClientOptions()
let callNetworkOptions = new CallNetworkOptions()

let iceServer = IceServer()
iceServer.urls = ["turn:20.202.255.255"]
iceServer.udpPort = 3478
iceServer.realm = "turn.azure.com"
iceServer.username = "turnserver1username"
iceServer.password = "turnserver1password"

callNetworkOptions.iceServers = [iceServer]

// Supply the network options when creating an instance of the CallClient
callClientOptions.network = callNetworkOptions
self.callClient = CallClient(options: callClientOptions);

重要

如果您在初始化 CallClient 時提供了 TURN 伺服器詳細資料,則所有媒體流量都只會流經這些 TURN 伺服器。 在嘗試在同儕節點之間建立連線時,將不會考量在您建立呼叫時通常會產生的任何其他 ICE 候選項目。 這表示只會考量 relay 候選項目。 若要深入了解不同類型的 ICE 候選項目,請參閱 RTCIceCandidate:type 屬性

目前,Android SDK 僅支援對媒體 Proxy 使用單一個 IPv4 位址UDP 通訊協定。 若未提供 UDP 連接埠,將會使用預設 UDP 連接埠 3478。 使用不支援的輸入呼叫 setIceServer 時,SDK 會擲回 Failed to set media proxy 錯誤,如下所示:

  • IceServers 清單中提供多個 ICE 伺服器。
  • IceServer 的 URL 清單中提供多個 URL。
  • URL 清單中提供 IPv6 URL。
  • 只提供 TCP 連接埠。
  • 未提供領域資訊。

如果提供的 ICE 伺服器資訊無效,則 CallClient 初始化就會失敗,並據以擲回錯誤。

在 Azure 中設定 TURN 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器。 若要部署 TURN 伺服器,請使用 coturn。 coturn 是適用於 VoIP 和 WebRTC 的 TURN 和 STUN 伺服器的免費開放原始碼實作。

設定 TURN 伺服器之後,您可以使用 WebRTC Trickle ICE 網頁上的指示加以測試。

透過 Proxy 處理訊號流量

若要提供 Proxy 伺服器的 URL,您必須在初始化 CallClient 時透過 Network 屬性將其傳入作為 CallClientOptions 的一部分。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 iOS SDK,以取得如何設定語音和視訊的快速入門。

let callClientOptions = CallClientOptions()
let callNetworkOptions = CallNetworkOptions()
callNetworkOptions.proxyUrl = proxyUrl
callClientOptions.network = callNetworkOptions
self.callClient = CallClient(options: callClientOptions)

// ...continue normally with your SDK setup and usage.

在 Azure 上設定訊號 Proxy 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器,並於其上部署 NGINX 伺服器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器

以下是可供您用作範例的 NGINX 設定:

events {
    multi_accept       on;
    worker_connections 65535;
}
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    map $request_method $access_control_header {
        OPTIONS '*';
    }
    server {
        listen <port_you_want_listen_on> ssl;
        ssl_certificate     <path_to_your_ssl_cert>;
        ssl_certificate_key <path_to_your_ssl_key>;
        location ~* ^/(.*?\.(com|net)(?::[\d]+)?)/(.*)$ {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin '*' always;
                add_header Access-Control-Allow-Credentials 'true' always;
                add_header Access-Control-Allow-Headers '*' always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type 'text/plain';
                add_header Content-Length 0;
                return 204;
            }
            resolver 1.1.1.1;
            set $ups_host $1;
            set $r_uri $3;
            rewrite ^/.*$ /$r_uri break;
            proxy_set_header Host $ups_host;
            proxy_ssl_server_name on;
            proxy_ssl_protocols TLSv1.2;
            proxy_ssl_ciphers DEFAULT;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass_request_headers on;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Proxy "";
            proxy_set_header Access-Control-Allow-Origin $access_control_header;
            proxy_pass https://$ups_host;
            proxy_redirect https://$ups_host https://$host/$ups_host;
            proxy_intercept_errors on;
            error_page 301 302 307 = @process_redirect;
            error_page 400 405 = @process_error_response;
        }
        location @process_redirect {
            set $saved_redirect_location '$upstream_http_location';
            resolver 1.1.1.1;
            proxy_pass $saved_redirect_location;
            add_header X-DBUG-MSG "301" always;
        }
        location @process_error_response {
            add_header Access-Control-Allow-Origin * always;
        }
    }
}

Proxy 功能適用於 Teams 身分識別和 Azure 通訊服務 Teams 互通性動作。

對媒體流量進行 Proxy 呼叫

以下幾節說明如何對媒體流量進行 Proxy 呼叫。

什麼是 TURN 伺服器?

很多時候,要在兩個同儕節點之間建立網路連線並不容易。 基於下列原因,直接連線可能無法運作:

  • 防火牆有嚴格的規則。
  • 同儕節點位於私人網路後方。
  • 電腦執行於網路位址轉譯 (NAT) 環境中。

若要解決這些網路連線問題,您可以使用採用 Traversal Using Relay NAT (TURN) 通訊協定來轉送網路流量的伺服器。 NAT 的工作階段周遊公用程式 (STUN) 和 TURN 伺服器是轉送伺服器。

使用 SDK 提供您的 TURN 伺服器詳細資料

若要提供 TURN 伺服器的詳細資料,您必須傳遞在初始化 CallClient 時要將哪個 TURN 伺服器作為 CallClientOptions 一部分的詳細資料。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Android SDK,以取得如何設定語音和視訊的快速入門。

CallClientOptions callClientOptions = new CallClientOptions();
CallNetworkOptions callNetworkOptions = new CallNetworkOptions();

IceServer iceServer = new IceServer();
iceServer.setUrls(Arrays.asList("turn:20.202.255.255"));
iceServer.setUdpPort(3478);
iceServer.setRealm("turn.azure.com"); // Realm information is required.
iceServer.setUsername("turnserver1username");
iceServer.setPassword("turnserver1password");

callNetworkOptions.setIceServers(Arrays.asList(iceServer));

// Supply the network options when creating an instance of the CallClient
callClientOptions.setNetwork(callNetworkOptions);
CallClient callClient = new CallClient(callClientOptions);

重要

如果您在初始化 CallClient 時提供了 TURN 伺服器詳細資料,則所有媒體流量都只會流經這些 TURN 伺服器。 在嘗試在同儕節點之間建立連線時,將不會考量在您建立呼叫時通常會產生的任何其他 ICE 候選項目。 這表示只會考量 relay 候選項目。 若要深入了解不同類型的 ICE 候選項目,請參閱 RTCIceCandidate:type 屬性

目前,Android SDK 僅支援對媒體 Proxy 使用單一個 IPv4 位址UDP 通訊協定。 若未提供 UDP 連接埠,將會使用預設 UDP 連接埠 3478。 使用不支援的輸入呼叫 setIceServer 時,SDK 會擲回 Failed to set media proxy 錯誤,如下所示:

  • IceServers 清單中提供多個 ICE 伺服器。
  • IceServer 的 URL 清單中提供多個 URL。
  • URL 清單中提供 IPv6 URL。
  • 只提供 TCP 連接埠。
  • 未提供領域資訊。

如果提供的 ICE 伺服器資訊無效,則 CallClient 初始化就會失敗,並據以擲回錯誤。

在 Azure 中設定 TURN 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器。 若要部署 TURN 伺服器,請使用 coturn。 coturn 是適用於 VoIP 和 WebRTC 的 TURN 和 STUN 伺服器的免費開放原始碼實作。

設定 TURN 伺服器之後,您可以使用 WebRTC Trickle ICE 網頁上的指示加以測試。

透過 Proxy 處理訊號流量

若要提供 Proxy 伺服器的 URL,您必須在初始化 CallClient 時透過 Network 屬性將其傳入作為 CallClientOptions 的一部分。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Android SDK,以取得如何設定語音和視訊的快速入門。

CallClientOptions callClientOptions = new CallClientOptions();
CallNetworkOptions callNetworkOptions = new CallNetworkOptions();
callNetworkOptions.setProxyUrl("https://myproxyserver.com");
callClientOptions.setNetwork(callNetworkOptions);
CallClient callClient = new CallClient(callClientOptions);

// ...continue normally with your SDK setup and usage.

在 Azure 上設定訊號 Proxy 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器,並於其上部署 NGINX 伺服器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器

以下是可供您用作範例的 NGINX 設定:

events {
    multi_accept       on;
    worker_connections 65535;
}
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    map $request_method $access_control_header {
        OPTIONS '*';
    }
    server {
        listen <port_you_want_listen_on> ssl;
        ssl_certificate     <path_to_your_ssl_cert>;
        ssl_certificate_key <path_to_your_ssl_key>;
        location ~* ^/(.*?\.(com|net)(?::[\d]+)?)/(.*)$ {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin '*' always;
                add_header Access-Control-Allow-Credentials 'true' always;
                add_header Access-Control-Allow-Headers '*' always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type 'text/plain';
                add_header Content-Length 0;
                return 204;
            }
            resolver 1.1.1.1;
            set $ups_host $1;
            set $r_uri $3;
            rewrite ^/.*$ /$r_uri break;
            proxy_set_header Host $ups_host;
            proxy_ssl_server_name on;
            proxy_ssl_protocols TLSv1.2;
            proxy_ssl_ciphers DEFAULT;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass_request_headers on;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Proxy "";
            proxy_set_header Access-Control-Allow-Origin $access_control_header;
            proxy_pass https://$ups_host;
            proxy_redirect https://$ups_host https://$host/$ups_host;
            proxy_intercept_errors on;
            error_page 301 302 307 = @process_redirect;
            error_page 400 405 = @process_error_response;
        }
        location @process_redirect {
            set $saved_redirect_location '$upstream_http_location';
            resolver 1.1.1.1;
            proxy_pass $saved_redirect_location;
            add_header X-DBUG-MSG "301" always;
        }
        location @process_error_response {
            add_header Access-Control-Allow-Origin * always;
        }
    }
}

Proxy 功能適用於 Teams 身分識別和 Azure 通訊服務 Teams 互通性動作。

對媒體流量進行 Proxy 呼叫

以下幾節說明如何對媒體流量進行 Proxy 呼叫。

什麼是 TURN 伺服器?

很多時候,要在兩個同儕節點之間建立網路連線並不容易。 基於下列原因,直接連線可能無法運作:

  • 防火牆有嚴格的規則。
  • 同儕節點位於私人網路後方。
  • 電腦執行於網路位址轉譯 (NAT) 環境中。

若要解決這些網路連線問題,您可以使用採用 Traversal Using Relay NAT (TURN) 通訊協定來轉送網路流量的伺服器。 NAT 的工作階段周遊公用程式 (STUN) 和 TURN 伺服器是轉送伺服器。

使用 SDK 提供您的 TURN 伺服器詳細資料

若要提供 TURN 伺服器的詳細資料,您必須傳遞在初始化 CallClient 時要將哪個 TURN 伺服器作為 CallClientOptions 一部分的詳細資料。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Windows SDK,以取得如何設定語音和視訊的快速入門。

CallClientOptions callClientOptions = new CallClientOptions();
CallNetworkOptions callNetworkOptions = new CallNetworkOptions();

IceServer iceServer = new IceServer();
iceServer.Uris = new List<Uri>() { new Uri("turn:20.202.255.255") }.AsReadOnly();
iceServer.UdpPort = 3478;
iceServer.Realm = "turn.azure.com";
iceServer.Username = "turnserver1username";
iceServer.Password = "turnserver1password";

callNetworkOptions.IceServers = new List<IceServer>() { iceServer }.AsReadOnly();

// Supply the network options when creating an instance of the CallClient
callClientOptions.Network = callNetworkOptions;
CallClient callClient = new CallClient(callClientOptions);

重要

如果您在初始化 CallClient 時提供了 TURN 伺服器詳細資料,則所有媒體流量都只會流經這些 TURN 伺服器。 在嘗試在同儕節點之間建立連線時,將不會考量在您建立呼叫時通常會產生的任何其他 ICE 候選項目。 這表示只會考量 relay 候選項目。 若要深入了解不同類型的 ICE 候選項目,請參閱 RTCIceCandidate:type 屬性

目前,Android SDK 僅支援對媒體 Proxy 使用單一個 IPv4 位址UDP 通訊協定。 若未提供 UDP 連接埠,將會使用預設 UDP 連接埠 3478。 使用不支援的輸入呼叫 setIceServer 時,SDK 會擲回 Failed to set media proxy 錯誤,如下所示:

  • IceServers 清單中提供多個 ICE 伺服器。
  • IceServer 的 URL 清單中提供多個 URL。
  • URL 清單中提供 IPv6 URL。
  • 只提供 TCP 連接埠。
  • 未提供領域資訊。

如果提供的 ICE 伺服器資訊無效,則 CallClient 初始化就會失敗,並據以擲回錯誤。

在 Azure 中設定 TURN 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器。 若要部署 TURN 伺服器,請使用 coturn。 coturn 是適用於 VoIP 和 WebRTC 的 TURN 和 STUN 伺服器的免費開放原始碼實作。

設定 TURN 伺服器之後,您可以使用 WebRTC Trickle ICE 網頁上的指示加以測試。

透過 Proxy 處理訊號流量

若要提供 Proxy 伺服器的 URL,您必須在初始化 CallClient 時透過 Network 屬性將其傳入作為 CallClientOptions 的一部分。 如需如何設定呼叫的詳細資訊,請參閱 Azure 通訊服務 Windows SDK,以取得如何設定語音和視訊的快速入門。

CallClientOptions callClientOptions = new CallClientOptions();
CallNetworkOptions callNetworkOptions = new CallNetworkOptions();
callNetworkOptions.ProxyUri = new Uri("https://myproxyserver.com");
callClientOptions.Network = callNetworkOptions;
CallClient callClient = new CallClient(callClientOptions);

// ...continue normally with your SDK setup and usage.

在 Azure 上設定訊號 Proxy 伺服器

您可以在 Azure 入口網站中建立 Linux 虛擬機器,並於其上部署 NGINX 伺服器。 如需詳細資訊,請參閱快速入門:在 Azure 入口網站中建立 Linux 虛擬機器

以下是可供您用作範例的 NGINX 設定:

events {
    multi_accept       on;
    worker_connections 65535;
}
http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    map $request_method $access_control_header {
        OPTIONS '*';
    }
    server {
        listen <port_you_want_listen_on> ssl;
        ssl_certificate     <path_to_your_ssl_cert>;
        ssl_certificate_key <path_to_your_ssl_key>;
        location ~* ^/(.*?\.(com|net)(?::[\d]+)?)/(.*)$ {
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin '*' always;
                add_header Access-Control-Allow-Credentials 'true' always;
                add_header Access-Control-Allow-Headers '*' always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
                add_header Access-Control-Max-Age 1728000;
                add_header Content-Type 'text/plain';
                add_header Content-Length 0;
                return 204;
            }
            resolver 1.1.1.1;
            set $ups_host $1;
            set $r_uri $3;
            rewrite ^/.*$ /$r_uri break;
            proxy_set_header Host $ups_host;
            proxy_ssl_server_name on;
            proxy_ssl_protocols TLSv1.2;
            proxy_ssl_ciphers DEFAULT;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass_header Authorization;
            proxy_pass_request_headers on;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Proxy "";
            proxy_set_header Access-Control-Allow-Origin $access_control_header;
            proxy_pass https://$ups_host;
            proxy_redirect https://$ups_host https://$host/$ups_host;
            proxy_intercept_errors on;
            error_page 301 302 307 = @process_redirect;
            error_page 400 405 = @process_error_response;
        }
        location @process_redirect {
            set $saved_redirect_location '$upstream_http_location';
            resolver 1.1.1.1;
            proxy_pass $saved_redirect_location;
            add_header X-DBUG-MSG "301" always;
        }
        location @process_error_response {
            add_header Access-Control-Allow-Origin * always;
        }
    }
}