次の方法で共有


呼び出しトラフィックを強制的に独自のサーバー経由でプロキシされるようにする

このチュートリアルでは、Azure Communication Services の呼び出しトラフィックを独自のサーバー経由でプロキシする方法について学習します。

特定の状況では、自分で制御できるサーバーにすべてのクライアント トラフィックをプロキシしておくと便利な場合があります。 SDK の初期化時に、トラフィックのルーティング先となるサーバーの詳細を指定できます。 一度有効にすると、すべてのメディア トラフィック (オーディオ/ビデオ/画面共有) が、Azure Communication Services の既定値ではなく、指定された TURN サーバーを通過します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • TURN サーバーを設定する。
  • シグナリング プロキシ サーバーを設定する。

前提条件

なし

プロキシ機能は、Azure Communication Services Calling SDK のパブリック バージョン 1.25.1 から一般提供になっています。 この機能を使用する場合は、必ずこの SDK またはそれ以降のバージョンの SDK を使用してください。 このチュートリアルでは、この機能がパブリック プレビューで最初に利用可能になった Calling SDK 1.13.0-beta.1 というバージョンを使用します。

メディア トラフィックを呼び出すプロキシ

以降のセクションでは、メディア トラフィックをプロキシ呼び出しする方法について説明します。

TURN サーバーとは

多くの場合、2 つのピア間のネットワーク接続を確立することは簡単ではありません。 直接接続は、次の理由で機能しない可能性があります。

  • 厳密な規則を持つファイアウォール。
  • プライベート ネットワークの背後にあるピア。
  • ネットワーク アドレス変換 (NAT) 環境で実行されているコンピューター。

これらのネットワーク接続の問題を解決するには、ネットワーク トラフィックをリレーするために、Traversal Using Relay NAT (TURN) プロトコルを使用するサーバーを使用できます。 Session Traversal Utilities for NAT (STUN) と TURN のサーバーはリレー サーバーです。

TURN サーバーの詳細を SDK に提供する

TURN サーバーの詳細を提供するには、CallClient の初期化時に、CallClientOptions の一部として使用する TURN サーバーの詳細を渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 property」を参照してください。

?transport クエリ パラメータが TURN URL の一部として存在しないか、udptcp、または tls 値のいずれでもない場合、既定の動作は UDP です。

指定された URL のいずれかが無効であるか、turn:turns:、または stun: のいずれかのスキーマがない場合、CallClient の初期化は失敗し、それに応じてエラーがスローされます。 スローされるエラー メッセージは、問題が発生した場合のトラブルシューティングに役立ちます。

CallClientOptions オブジェクトの API リファレンスとオブジェクト内の networkConfiguration プロパティについては、CallClientOptions に関するページを参照してください。

Azure で TURN サーバーを設定する

Azure portal で Linux 仮想マシンを作成できます。 詳細については、クイック スタート: Azure portal で Linux 仮想マシンを作成する」を参照してください。 TURN サーバーをデプロイするには、coturn を使用します。 Coturn は、VoIP および WebRTC 用の TURN および STUN サーバーの無料のオープンソース実装です。

TURN サーバーを設定したら、WebRTC Trickle ICE Web ページの手順に従ってテストできます。

シグナリング トラフィックをプロキシ経由にする

プロキシ サーバーの URL を指定するには、CallClient の初期化中に CallClientOptions の一部として渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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.

Note

指定されたプロキシ URL が無効な URL の場合、CallClient の初期化は失敗し、それに応じてエラーがスローされます。 スローされるエラー メッセージは、問題が発生した場合のトラブルシューティングに役立ちます。

CallClientOptions オブジェクトの API リファレンスとオブジェクト内の networkConfiguration プロパティについては、CallClientOptions に関するページを参照してください。

Express.js でシグナリング プロキシ ミドルウェアを設定する

Express js サーバー セットアップでプロキシ ミドルウェアを作成し、http-proxy-middleware npm パッケージを使用して、すべての URL をそれを経由してリダイレクトさせることもできます。 そのパッケージの createProxyMiddleware 関数は、簡単なリダイレクト プロキシのセットアップに必要なものをカバーする必要があります。 すべての 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 でシグナリング プロキシ サーバーを設定する

Azure portal で Linux 仮想マシンを作成し、その上に NGINX サーバーをデプロイできます。 詳細については、クイック スタート: Azure portal で 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;
        }
    }
}

プロキシ機能は、Teams ID と Azure Communication Services Teams 相互運用性アクションでは使用 "できません"。

メディア トラフィックを呼び出すプロキシ

以降のセクションでは、メディア トラフィックをプロキシ呼び出しする方法について説明します。

TURN サーバーとは

多くの場合、2 つのピア間のネットワーク接続を確立することは簡単ではありません。 直接接続は、次の理由で機能しない可能性があります。

  • 厳密な規則を持つファイアウォール。
  • プライベート ネットワークの背後にあるピア。
  • ネットワーク アドレス変換 (NAT) 環境で実行されているコンピューター。

これらのネットワーク接続の問題を解決するには、ネットワーク トラフィックをリレーするために、Traversal Using Relay NAT (TURN) プロトコルを使用するサーバーを使用できます。 Session Traversal Utilities for NAT (STUN) と TURN のサーバーはリレー サーバーです。

SDK を使用して TURN サーバーの詳細を提供する

TURN サーバーの詳細を提供するには、CallClient の初期化時に、CallClientOptions の一部として使用する TURN サーバーの詳細を渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 property」を参照してください。

現在、Android SDK では、メディア プロキシ用に 単一の IPv4 アドレスUDP プロトコルのみがサポートされています。 UDP ポートが指定されていない場合は、既定の UDP ポート 3478 が使用されます。 次のようにサポートされていない入力で setIceServer を呼び出すと、SDK は Failed to set media proxy エラーをスローします。

  • IceServers リストで、複数の ICE サーバーが指定されている。
  • IceServer の URL リストで、複数の URL が指定されている。
  • URL リストで IPv6 URL が指定されている。
  • TCP ポートのみが指定されている。
  • 領域情報が指定されていない。

指定された ICE サーバー情報が無効な URL の場合、CallClient の初期化は失敗し、それに応じてエラーがスローされます。

Azure で TURN サーバーを設定する

Azure portal で Linux 仮想マシンを作成できます。 詳細については、クイック スタート: Azure portal で Linux 仮想マシンを作成する」を参照してください。 TURN サーバーをデプロイするには、coturn を使用します。 Coturn は、VoIP および WebRTC 用の TURN および STUN サーバーの無料のオープンソース実装です。

TURN サーバーを設定したら、WebRTC Trickle ICE Web ページの手順に従ってテストできます。

シグナリング トラフィックをプロキシ経由にする

プロキシサーバーの URL を指定するには、CallClient を初期化する際に、CallClientOptions の一部としてプロパティ Network を通して渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 でシグナリング プロキシ サーバーを設定する

Azure portal で Linux 仮想マシンを作成し、その上に NGINX サーバーをデプロイできます。 詳細については、クイック スタート: Azure portal で 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;
        }
    }
}

プロキシ機能は、Teams ID と Azure Communication Services Teams 相互運用性アクションでは使用 "できません"。

メディア トラフィックを呼び出すプロキシ

以降のセクションでは、メディア トラフィックをプロキシ呼び出しする方法について説明します。

TURN サーバーとは

多くの場合、2 つのピア間のネットワーク接続を確立することは簡単ではありません。 直接接続は、次の理由で機能しない可能性があります。

  • 厳密な規則を持つファイアウォール。
  • プライベート ネットワークの背後にあるピア。
  • ネットワーク アドレス変換 (NAT) 環境で実行されているコンピューター。

これらのネットワーク接続の問題を解決するには、ネットワーク トラフィックをリレーするために、Traversal Using Relay NAT (TURN) プロトコルを使用するサーバーを使用できます。 Session Traversal Utilities for NAT (STUN) と TURN のサーバーはリレー サーバーです。

SDK を使用して TURN サーバーの詳細を提供する

TURN サーバーの詳細を提供するには、CallClient の初期化時に、CallClientOptions の一部として使用する TURN サーバーの詳細を渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 property」を参照してください。

現在、Android SDK では、メディア プロキシ用に 単一の IPv4 アドレスUDP プロトコルのみがサポートされています。 UDP ポートが指定されていない場合は、既定の UDP ポート 3478 が使用されます。 次のようにサポートされていない入力で setIceServer を呼び出すと、SDK は Failed to set media proxy エラーをスローします。

  • IceServers リストで、複数の ICE サーバーが指定されている。
  • IceServer の URL リストで、複数の URL が指定されている。
  • URL リストで IPv6 URL が指定されている。
  • TCP ポートのみが指定されている。
  • 領域情報が指定されていない。

指定された ICE サーバー情報が無効な URL の場合、CallClient の初期化は失敗し、それに応じてエラーがスローされます。

Azure で TURN サーバーを設定する

Azure portal で Linux 仮想マシンを作成できます。 詳細については、クイック スタート: Azure portal で Linux 仮想マシンを作成する」を参照してください。 TURN サーバーをデプロイするには、coturn を使用します。 Coturn は、VoIP および WebRTC 用の TURN および STUN サーバーの無料のオープンソース実装です。

TURN サーバーを設定したら、WebRTC Trickle ICE Web ページの手順に従ってテストできます。

シグナリング トラフィックをプロキシ経由にする

プロキシサーバーの URL を指定するには、CallClient を初期化する際に、CallClientOptions の一部としてプロパティ Network を通して渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 でシグナリング プロキシ サーバーを設定する

Azure portal で Linux 仮想マシンを作成し、その上に NGINX サーバーをデプロイできます。 詳細については、クイック スタート: Azure portal で 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;
        }
    }
}

プロキシ機能は、Teams ID と Azure Communication Services Teams 相互運用性アクションでは使用 "できません"。

メディア トラフィックを呼び出すプロキシ

以降のセクションでは、メディア トラフィックをプロキシ呼び出しする方法について説明します。

TURN サーバーとは

多くの場合、2 つのピア間のネットワーク接続を確立することは簡単ではありません。 直接接続は、次の理由で機能しない可能性があります。

  • 厳密な規則を持つファイアウォール。
  • プライベート ネットワークの背後にあるピア。
  • ネットワーク アドレス変換 (NAT) 環境で実行されているコンピューター。

これらのネットワーク接続の問題を解決するには、ネットワーク トラフィックをリレーするために、Traversal Using Relay NAT (TURN) プロトコルを使用するサーバーを使用できます。 Session Traversal Utilities for NAT (STUN) と TURN のサーバーはリレー サーバーです。

SDK を使用して TURN サーバーの詳細を提供する

TURN サーバーの詳細を提供するには、CallClient の初期化時に、CallClientOptions の一部として使用する TURN サーバーの詳細を渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 property」を参照してください。

現在、Android SDK では、メディア プロキシ用に 単一の IPv4 アドレスUDP プロトコルのみがサポートされています。 UDP ポートが指定されていない場合は、既定の UDP ポート 3478 が使用されます。 次のようにサポートされていない入力で setIceServer を呼び出すと、SDK は Failed to set media proxy エラーをスローします。

  • IceServers リストで、複数の ICE サーバーが指定されている。
  • IceServer の URL リストで、複数の URL が指定されている。
  • URL リストで IPv6 URL が指定されている。
  • TCP ポートのみが指定されている。
  • 領域情報が指定されていない。

指定された ICE サーバー情報が無効な URL の場合、CallClient の初期化は失敗し、それに応じてエラーがスローされます。

Azure で TURN サーバーを設定する

Azure portal で Linux 仮想マシンを作成できます。 詳細については、クイック スタート: Azure portal で Linux 仮想マシンを作成する」を参照してください。 TURN サーバーをデプロイするには、coturn を使用します。 Coturn は、VoIP および WebRTC 用の TURN および STUN サーバーの無料のオープンソース実装です。

TURN サーバーを設定したら、WebRTC Trickle ICE Web ページの手順に従ってテストできます。

シグナリング トラフィックをプロキシ経由にする

プロキシサーバーの URL を指定するには、CallClient を初期化する際に、CallClientOptions の一部としてプロパティ Network を通して渡す必要があります。 呼び出しの設定方法の詳細については、Azure Communication Services 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 でシグナリング プロキシ サーバーを設定する

Azure portal で Linux 仮想マシンを作成し、その上に NGINX サーバーをデプロイできます。 詳細については、クイック スタート: Azure portal で 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;
        }
    }
}