次の方法で共有


Microsoft リアルタイム通信 API を使用してリッチ クライアント通信を拡張する

Jim Huang
Sr. Technical Marketing Engineer
Intel Corporation

February 2003
最終更新日 2003 年 9 月 18 日

適用対象:
    Microsoft(R) Windows(R) XP

要約: コミュニティを作成し、関係者が参加可能かどうかの状態を追跡するために、リアルタイム通信 (RTC) クライアント API を使用して、プレゼンス情報、プロファイル、友人の一覧などの機能を組み込む方法について説明します。この記事は、以前の記事「Microsoft Real-Time Communications API による豊富なクライアント通信機能の統合」を基にして書かれています。

RTCSampleCode.zip をダウンロードしてください。サンプル プログラム ファイル内では実際のコメント行は英語で書かれていますが、この記事内では説明目的で日本語で書かれています。

目次

はじめに
事前準備
プレゼンスと友人一覧を通知するために初期化する
プレゼンスを有効にして検出する
SIP サーバーでの登録
XML プロファイルを作成する
友人の一覧およびオンラインのメンバ (Watcher) オブジェクトを作成する
プロファイルを登録解除して無効にする
パフォーマンスのために最適化する
まとめ
リソース

はじめに

以前の記事「Microsoft Real-Time Communications API による豊富なクライアント通信機能の統合」で、リアルタイム通信 (RTC) クライアント API を使用して、オーディオ/ビデオ会議、インスタント メッセージング、アプリケーション共有などの機能を簡単にアプリケーションに統合できることを説明しました。

この記事ではこれをさらに拡大し、RTC クライアント API を使用してプレゼンス情報、プロファイル、友人の一覧などの機能を追加することで、いかに簡単にコミュニティを作成できるかについて説明します。最初の記事で作成した Windows XP アプリケーションを使用しながら、この機能を有効にする手順を説明していきます。

事前準備

ここでの説明は、XML スキーマに関する知識があることを前提としています。RTC オブジェクトの初期化については、最初の記事を参照してください。

この記事で使用するソース コードには 2 つのバージョンがあります。

  • RTCSampleCode.exe サンプル コードには、オーディオ/ビデオ会議、インスタント メッセージング、プレゼンス、および友人の一覧を有効にする機能がすべて含まれています。
  • インテル(R) の「 Real-Time Communication Sample Application 」(英語) ページから入手可能な AVDConf2.exe サンプル コードには、RTCSample.exe サンプル コードと同じ機能に加えて、ホワイトボード共有、アプリケーション共有、ハイパースレッディング テクノロジ搭載のインテル(R) Pentium(R) 4 プロセッサの検出、CPU 使用率メーターなどの機能が含まれています。AVDConf2.exe コードは、RTCSample.exe の多数のサンプルを使用し、さらに MSDN (Microsoft Software Developers Network) Web サイトの複数の RTC コードを使用しています。

注: ハイパースレッディング テクノロジには、3.06 GHz 以上のインテル Pentium 4 プロセッサを搭載したコンピュータ システム、このテクノロジを利用するチップ セットと BIOS、およびこのテクノロジ向けに最適化されたオペレーティング システムが必要です。パフォーマンスは、使用するハードウェアとソフトウェアによって異なります。詳細については、「Hyper-Threading Technology」(英語) を参照してください。

必要な環境は次のとおりです。

  • SP5 を適用した Visual Studio(R) 6.0
  • Microsoft Platform SDK
  • SIP サーバーまたは Windows .NET Server Beta 3

セッション開始プロトコル (SIP) サーバー

現在、プレゼンス、プロファイル、および友人一覧をアプリケーションに統合するには、SIP サーバーまたは Windows .NET Server Beta 3 が必要です。SIP レジスタ サーバーは、友人一覧機能を有効にする場合などにプレゼンス情報が要求されるときに必要となります。ユーザーは、このサービスを使用して各自のプレゼンス情報をサーバーに登録したり、他のユーザーのプレゼンス情報を取得したりすることができます。

サーバーは、セッション開始プロトコル (SIP) およびその関連プロトコルである SIMPLE を、基盤となる通信プロトコルとして使用します。SIP はマルチモーダル通信に対して優れたサポートを提供します。SIP および SIMPLE は、単にテキスト メッセージングを共有するためのプロトコルではなく、音声、ビデオ、アプリケーション共有などを管理することができます。

セッション開始プロトコル

SIP プロトコルは、IP ネットワークでセッションを開始し、プレゼンス情報を登録します。セッションは、単純な双方向の PC 間通信の場合もあれば、協調作業を行うマルチメディア会議セッションの場合もあります。SIP は、セッションの確立、操作、および切断を行う Internet Engineering Task Force (IETF) シグナリング プロトコルです。SIP の主な目的は、セッションの開始者が潜在的なセッション参加者に対し、その居場所に関係なく招待を配信できるようにすることです。SIP は、"単純で拡張性のある" IP テレフォニー シグナリング プロトコルと評されています。

プレゼンスと友人一覧を通知するために初期化する

プレゼンス、友人一覧、およびプロファイルに関する新たなイベント通知を受け取るには、次に示すイベント フィルタ マスクを設定して、アプリケーションが RTC 層からイベント通知を受信できるようにします。これらのイベント マスクは、最初のサンプル アプリケーションで設定されたイベント マスクに追加されます。

#define RTCEF_REGISTRATION_STATE_CHANGE     0x00000002
#define RTCEF_BUDDY                               0x00000100
#define RTCEF_WATCHER                             0x00000200
#define RTCEF_PROFILE                             0x00000400

すべてのイベントを簡単に登録するには、RTCEF_ALL マクロを使用して、すべてのイベントをアプリケーションに送信するよう RTC 層に通知します。

   long lEventMask = RTCEF_ALL;

RTC イベントを処理する

次のコードでは、SIP サーバーにユーザー プロファイルが登録され、プレゼンス情報と友人一覧イベントが送受信されると処理される追加のイベントを示しています。イベントが受信されるたびに、イベント フィルタ メソッドが適切な RTC インターフェイスを使用して受信したイベントを処理します。

HRESULT CAVDConfDlg::OnRTCEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
    IDispatch * pDisp = (IDispatch *)lParam;
    RTC_EVENT enEvent = (RTC_EVENT)wParam;
    HRESULT hr;

    // RTC_EVENT タイプに基づいて、
    // 適切なイベント インターフェイスを照会し、イベントを
    // 処理するヘルパー メソッドを呼び出します。

    switch ( wParam )
    {
   ... .

   case RTCE_REGISTRATION_STATE_CHANGE:
            {
                IRTCRegistrationStateChangeEvent * pEvent = NULL;
                // 現在のセッションに関連付けられたイベント ハンドルを取得します。
   hr = pDisp->QueryInterface( IID_IRTCSessionStateChangeEvent,
                                            (void **)&pEvent );

                if (SUCCEEDED(hr))
                {
                    OnRTCSessionStateChangeEvent(pEvent);
                    SAFE_RELEASE(pEvent);
                }                                            
            }
   break;

   case RTCE_BUDDY:
            {
                IRTCBuddyEvent * pEvent = NULL;
    hr = pDisp->QueryInterface( IID_IRTCBuddyEvent,
                                            (void **)&pEvent );

                if (SUCCEEDED(hr))
                {
                    OnRTCBuddyEvent(pEvent);
                    SAFE_RELEASE(pEvent);
                }
   }
   break;

   case RTCE_WATCHER:
            {
                IRTCWatcherEvent * pEvent = NULL;
                hr = pDisp->QueryInterface( IID_IRTCWatcherEvent,
                                            (void **)&pEvent );

                if (SUCCEEDED(hr))
                {
                    OnRTCWatcherEvent(pEvent);
                    SAFE_RELEASE(pEvent);
                }            }
   break;
    }
   ... .
}

プレゼンスを有効にして検出する

プレゼンス情報サービスによって、ユーザーは連絡先のプレゼンス状態を追跡したり、自分の状態を連絡先に通知したり、連絡先の現在の場所情報を管理するレジスタ サーバーを介して自分の友人 (または連絡先) に電話したりすることができます。場所とは PC または電話のいずれかで、将来的には携帯電話やポケットベル、ハンドヘルド デバイスも含まれるようになります。

ms997616.rtc_enhancerichclient-real-timecomm-1(ja-jp,MSDN.10).jpg

図 1. 友人の一覧とプレゼンス状態を表示するサンプル UI

次の図は、SIP サーバーにクライアントを登録し、プレゼンスを有効にするための高レベルの手順を示しています。

ms997616.rtc_enhancerichclient-real-timecomm-2(ja-jp,MSDN.10).gif

図 2. プロファイルとプレゼンス サービスを有効にするための手順

SIP サーバーでの登録

プレゼンス サービスを有効にするには、プロファイル オブジェクトを作成する必要があります。プロファイル オブジェクトは、IRTCClientProvisioning::CreateProfile メソッドによって作成されます。プロファイル オブジェクトを作成するには、プロビジョニング スキーマに準拠した XML 文字列をクライアント アプリケーションで作成する必要があります。XML スキーマには次の属性があります。

  • プロビジョニング設定 - プロファイルの一意の ID。
  • ユーザー設定 - ユーザーの URI、領域、およびログイン アカウント情報。
  • クライアント設定 - 通信リンクとは関係のないクライアント アプリケーションに関する情報。この情報は必須ではありません。
  • プロバイダ設定 - インターネット テレフォニー サービス プロバイダ (ITSP) に関する情報。
  • SIP サーバー設定 - 利用可能な SIP サーバー、SIP サーバーの役割、およびサーバーがサポートできるセッションの種類を指定します。

ユーザーを SIP サーバー上で登録するには、RTC クライアント API に SIP サーバーとの通信方法を指示する XML プロファイル文字列をクライアント側で作成する必要があります。XML 文字列を作成したら、IRTCClientProvisioning::CreateProfile() メソッドを呼び出してプロファイル オブジェクトを作成します。次に、IRTCClientProvisioning::EnableProfile() メソッドを呼び出してユーザーを RTC サーバー上で登録し、そのサーバー上でプロファイルが登録されるセッションの種類を指定します。指定可能な登録の種類には、 着信する PC 間セッションを許可 (RTCRF_REGISTER_INVITE_SESSIONS)、着信するインスタント メッセージング セッションを許可 (RTCRF_REGISTER_MESSAGE_SESSIONS)、着信するオンラインのメンバ (Watcher) を許可 (RTCRF_REGISTER_PRESENCE)、およびすべての登録の種類を許可 (RTCRF_REGISTER_ALL) があります。RTCRF_REGISTER_PRESENCE または RTCRF_REGISTER_ALL を設定すると、クライアントが SIP の SUBSCRIBE メソッドを受け付けることがレジスタ サーバーに通知されます。これによってユーザーは、他のユーザーのプレゼンス状態の変更をそれらのユーザーに通知できるようになります。また、連絡先のプレゼンス状態変更の通知、および自分のプレゼンスをオンラインのメンバ (Watcher) の一覧に追加しようとしているユーザーの通知を受け取ることができます。

オンラインのメンバ (Watcher) オブジェクトによって、ユーザーの状態が友人一覧に提供されます。オンラインのメンバ (Watcher) は、メンバ (Presentity) の状態を照会することができ、友人一覧内のユーザーの状態が変更された場合に通知を受け取ります。またオンラインのメンバ (Watcher) を使用して、ユーザーはそのメンバ (Presentity) の状態を他のユーザーに対してブロックまたは許可することができます。

サンプル コードには、ユーザーを登録し、プレゼンスと友人一覧を有効にする手順が示されています。

HRESULT CAVDConfDlg::DoSIPLogin(BSTR bXMLObj)
{
    HRESULT hr;

   ... .

    // RTC クライアントのプロビジョニング インターフェイスを取得します。
    IRTCClientProvisioning * pProv = NULL;

    hr = m_pClient->QueryInterface(
            IID_IRTCClientProvisioning,
            (void **)&pProv);

    if (FAILED(hr))
    {
      // 照会インターフェイスが失敗しました。
           return hr;
    }

    // XML プロビジョニング ドキュメントから
    // RTC プロファイル オブジェクトを作成します。
    hr = pProv->CreateProfile(bXMLObj, &m_pProfile);

    SAFE_FREE_STRING(bXMLObj);

    if (FAILED(hr))
    {
        // CreateProfile が失敗しました。
        SAFE_RELEASE(pProv);
        return hr;
    }

    // RTC プロファイル オブジェクトを有効にします。
    hr = pProv->EnableProfile(m_pProfile, RTCRF_REGISTER_ALL);

    SAFE_RELEASE(pProv);

    if (FAILED(hr))
    {
        // EnableProfile が失敗しました。
        return hr;    
    }

    // プレゼンスを有効にします。
    // プロファイルを有効にしたら、直ちにプレゼンスを有効にするのが最善の処理です。
    // これによって、着信するオンラインのメンバ (Watcher) が失われないようにします。
   
   // 機能の定義については、この後の EnablePresence() メソッドを参照してください。
    hr = EnablePresence(TRUE);

    if (FAILED(hr))
    {
        // DoEnablePresence が失敗しました。
        DoSIPLogoff();   // 機能のサンプルについては、コード サンプル AVDConf2.exe を参照してください。
        return hr;
    }


   return S_OK;
}

これでプロファイルが有効になったので、プレゼンスも有効にして着信するオンラインのメンバ (Watcher) イベントが失われないようにします。EnablePresence() メソッドには、友人の一覧を作成する方法も示されています。

HRESULT CAVDConfDlg::EnablePresence(BOOL bEnable)
{
    IRTCClientPresence * pPresence = NULL;
    HRESULT hr;

    // 友人の一覧をクリーンアップします。
    ClearBuddyList();

    // RTC クライアントのプレゼンス インターフェイスを取得します。
    hr = m_pClient->QueryInterface(
            IID_IRTCClientPresence,
            (void **)&pPresence);

    if (FAILED(hr))
    {
        // QueryInterface が失敗しました。
        return hr;
    }

    // プレゼンス記憶域の場所を取得します。
    VARIANT varStorage;
    VariantInit(&varStorage);
    varStorage.vt = VT_BSTR;
    varStorage.bstrVal = SysAllocString(L"presence.xml");

    // プレゼンスを無効にする場合は、プレゼンス データの最新のコピーを
    // presence.xml ファイルに保存します。
    if (!bEnable && m_bPresenceEnabled)
    {
        hr = pPresence->Export(varStorage);

        if (FAILED(hr))
        {
            // Export が失敗しました。
            SAFE_RELEASE(pPresence);
            VariantClear(&varStorage);
            return hr;
        }
    }

    // プレゼンスを有効にします。
    hr = pPresence->EnablePresence(
        bEnable ? VARIANT_TRUE : VARIANT_FALSE, varStorage);
    
    VariantClear(&varStorage);

    if (FAILED(hr))
    {
        // EnablePresence が失敗しました。
        SAFE_RELEASE(pPresence);
        return hr;
    }

    // 有効フラグを設定します。
    m_bPresenceEnabled = bEnable;

    // プレゼンスを無効にする場合は、
    // プレゼンス データをクリーンアップします。
    if (!bEnable)
    {
        // 友人をクリーンアップします。
        IRTCEnumBuddies * pEnumBuddy = NULL;
        IRTCBuddy * pBuddy = NULL;

      if (FAILED(hr))
      {
            // 友人の列挙に失敗しました。
            SAFE_RELEASE(pPresence);
            return hr;
      }
        
      // ユーザーの友人一覧を列挙します。     
      hr = pPresence->EnumerateBuddies(&pEnumBuddy);
   
        if (FAILED(hr))
        {
            // 友人の列挙に失敗しました
            SAFE_RELEASE(pPresence);
            return hr;
        }

        while (pEnumBuddy->Next(1, &pBuddy, NULL) == S_OK)
        {
            pPresence->RemoveBuddy(pBuddy);

            SAFE_RELEASE(pBuddy);
        }

        SAFE_RELEASE(pEnumBuddy);

        // オンラインのメンバ (Watcher) をクリーンアップします。
        IRTCEnumWatchers * pEnumWatcher = NULL;
        IRTCWatcher * pWatcher = NULL;

        hr = pPresence->EnumerateWatchers(&pEnumWatcher);
   
        if (FAILED(hr))
        {
            // オンラインのメンバ (Watcher) の列挙に失敗しました。
            SAFE_RELEASE(pPresence);
            return hr;
        }

        while (pEnumWatcher->Next(1, &pWatcher, NULL) == S_OK)
        {
            pPresence->RemoveWatcher(pWatcher);

            SAFE_RELEASE(pWatcher);
        }

        SAFE_RELEASE(pEnumWatcher);
    }

    SAFE_RELEASE(pPresence);

    return S_OK;
}

pPresence->EnablePresence() 関数の 2 番目のパラメータに注目してください。この関数は、友人の一覧および許可またはブロックされているオンラインのメンバ (Watcher) の一覧を格納するための可変記憶域を必要とします。可変記憶域は、ファイル名 (BSTR)、DOMDocument オブジェクト、または IStream、ISequentialStream、IPersistStream のいずれかをサポートするオブジェクトのいずれかの形式をとります。

RTC サーバーに登録すると、登録の完了または失敗を示す RTCE_REGISTRATION_STATE_CHANGE イベントがアプリケーションに送信されます。

プレゼンス サービスは、サーバーでプロファイルを登録する前に有効にすることができます。下の図は、登録に先だってプレゼンス サービスを有効にする方法を示しています。

これによってユーザーは、サーバーで登録する前にそれぞれの状態を設定することができます。ユーザーは SIP サーバーでの登録が可能である一方で、自分のオンラインのメンバ (Watcher) には自分を "オフライン" として表示し、連絡先の状態を見ることができます。この機能は、ユーザーが割り込みを行うことなくグループのプレゼンス状態を監視する必要がある場合に役立ちます。

ms997616.rtc_enhancerichclient-real-timecomm-3(ja-jp,MSDN.10).gif

図 3. 登録前にプレゼンスを有効にするための手順

CreateProfile() メソッドは、プレゼンス状態を設定した後に呼び出せることに注意してください。

次に示すのは XML スキーマです。

<?xml version="1.0" ?>
  
<Schema name="ProvisioningSchema.xml" 
        xmlns="urn:schemas-microsoft-com:xml-data" 
        xmlns:dt="urn:schemas-microsoft-com:datatypes">
     <comments>Schema Version MajorRevisionNumber = 1 
                              MinorRevisionNumber = 0
</comments> 
  
<ElementType name="provision" model="closed">
     <AttributeType name="key" required="yes" /> 
     <attribute type="key" /> 
     <AttributeType name="name" required="yes" /> 
     <attribute type="name" /> 
     <AttributeType name="expires" dt:type="dateTime.tz" /> 
     <attribute type="expires" /> 
     <element type="user" minOccurs="1" maxOccurs="1" /> 
     <element type="sipsrv" minOccurs="1" maxOccurs="*" /> 
     <element type="client" minOccurs="0" maxOccurs="1" /> 
     <element type="provider" minOccurs="0" maxOccurs="1" /> 
</ElementType>
  
<ElementType name="user" model="closed">
     <AttributeType name="uri" required="yes" /> 
     <attribute type="uri" /> 
     <AttributeType name="account" required="no" /> 
     <attribute type="account" /> 
     <AttributeType name="name" required="no" /> 
     <attribute type="name" /> 
     <AttributeType name="password" required="no" /> 
     <attribute type="password"   /> 
     <AttributeType name="realm" required="no" /> 
     <attribute type="realm" /> 
</ElementType>
  
<ElementType name="client" model="closed">
     <AttributeType name="name" required="yes" /> 
     <attribute type="name" /> 
     <AttributeType name="banner" 
                    dt:type="bool" 
                    required="no" /> 
     <attribute type="banner" /> 
     <AttributeType name="updates" 
                    dt:type="bool" 
                    required="no" /> 
     <attribute type="updates" /> 
     <AttributeType name="minver" 
                    dt:type="fixed.14.4" 
                    required="no"/>
     <attribute type="minver" /> 
     <AttributeType name="curver" 
                    dt:type="fixed.14.4" 
                    required="no"/>
     <attribute type="curver" /> 
     <AttributeType name="updateuri" 
                    dt:type="uri" 
                    required="no" />
     <attribute type="updateuri" /> 
     <element type="data" minOccurs="0" maxOccurs="1" />
</ElementType>
  
<ElementType name="data" model="open" /> 
  
<ElementType name="provider" model="closed" content="mixed">
     <AttributeType name="name" /> 
     <attribute type="name" /> 
     <AttributeType name="homepage" dt:type="uri" required="no" />
     <attribute type="homepage" /> 
     <AttributeType name="helpdesk" dt:type="uri" required="no" />
     <attribute type="helpdesk" /> 
     <AttributeType name="personal" dt:type="uri" required="no" /> 
     <attribute type="personal" /> 
     <AttributeType name="calldisplay" dt:type="uri" required="no" /> 
     <attribute type="calldisplay" /> 
     <AttributeType name="idledisplay" dt:type="uri" required="no" /> 
     <attribute type="idledisplay" /> 
     <element type="data" /> 
</ElementType>
  
<ElementType name="sipsrv" model="closed" content="mixed">
     <AttributeType name="addr" required="yes" /> 
     <attribute type="addr" /> 
     <AttributeType name="protocol" 
                    dt:type="enumeration" 
                    dt:values="TCP UDP TLS" 
                    required="yes" /> 
     <attribute type="protocol" /> 
     <AttributeType name="auth" 
                    dt:type="enumeration" 
                    dt:values="basic digest" 
                    required="no" /> 
     <attribute type="auth" /> 
     <AttributeType name="role" 
                    dt:type="enumeration" 
                    dt:values="proxy registrar" 
                    required="yes" /> 
     <attribute type="role" /> 
     <element type="session" minOccurs="0" maxOccurs="*" /> 
</ElementType>
  
<ElementType name="session" model="closed">
     <AttributeType name="party" 
                    dt:type="enumeration" 
                    dt:values="first third" /> 
     <attribute type="party" /> 
     <AttributeType name="type" 
                    dt:type="enumeration" 
                    dt:values="pc2pc pc2ph ph2ph im" /> 
     <attribute type="type" /> 
</ElementType>
  
</Schema>

XML プロファイルを作成する

次のコードは、XML プロファイル文字列を作成する方法を示しています。

HRESULT CSIPLogin::CreateXMLProvision(LPSTR szURI, LPSTR szSIPIP, 
                  LPSTR szTransport, BSTR *bstrBuf)
{
   ... .
    
   // XML プロビジョニング ドキュメントを生成します
      wsprintf(szBuf, "<provision key=\"AVDConf_2\" name=\"AVDConf_2\">"
           "<user uri=\"%s\" account=\"\" password=\"\" realm=\"%s\" />"
           "<sipsrv addr=\"%s\" protocol=\"%s\" %s role=\"proxy\">"
           "<session party=\"first\" type=\"pc2pc\" />"
           "<session party=\"first\" type=\"pc2ph\" />"
           "<session party=\"first\" type=\"im\" />"
           "</sipsrv>"
           "<sipsrv addr=\"%s\" protocol=\"%s\" %s role=\"registrar\"/>"
           "</provision>",
           szURIBuf, szRealm,
           szSIPIP, szTransport, bBasicAuth ? "auth=\"basic\"" : "",
          szSIPIP, szTransport, bBasicAuth ? "auth=\"basic\"" : ""
        );

   ... .

   return S_OK;
}

上記のサンプル アプリケーションおよびコードでは、アカウントのユーザー ID とパスワードを組み込む必要がありませんでした。これは、SIP サーバーによる要求がなかったからです。ただし、SIP サーバーがログイン アカウントを要求することがわかっている場合は、SIP サーバーにログインするためのユーザー ID とパスワードをプロファイル文字列に記述できます。登録に必要な情報は、ユーザーの Uniform Resource Identifier (URI)、領域またはドメイン、RTC サーバー IP、認証方法、およびサーバーとの通信に使用するトランスポートだけです。サポートされているトランスポートは、TCP、UDP、および TLS です。使用された SIP サーバーは、基本認証とダイジェスト認証の両方をサポートしていました。基本認証を使用する場合は、セキュリティ上の理由からトランスポートに TLS を使用する必要があります。

友人の一覧およびオンラインのメンバ (Watcher) オブジェクトを作成する

プロファイルを登録し、プレゼンスを有効にしたら、後は簡単に新しいユーザーを友人の一覧に追加できます。プレゼンスを有効にするメソッドを提供する IRTCClientPresence インターフェイスを使用して、友人の追加と削除、オンラインのメンバ (Watcher) の列挙、ローカルのプレゼンス状態の設定を行い、アプリケーションで新しいオンラインのメンバ (Watcher) からのサブスクリプションを処理する方法を決定し、さらにプライバシー モードを設定します。次に示すサンプル コードではプライバシー モードの実装方法は示されませんが、この機能によって、電話を許可された関係者の個別一覧をユーザーが作成できる点は注目に値します。

    // RTC クライアント プレゼンス インターフェイスを取得します。
    IRTCClientPresence * pPresence = NULL;

    hr = m_pClient->QueryInterface(
            IID_IRTCClientPresence,
            (void **)&pPresence);

    if (FAILED(hr))
    {
        // QueryInterface が失敗しました。
      char szBuf[256];

      wsprintf (szBuf, "Failed to Query Presence Interface\nErr = 0x%x", hr );
      MessageBox ( szBuf );
        return hr;
    }

    // 友人を追加します。
    IRTCBuddy * pBuddy = NULL;

    hr = pPresence->AddBuddy(
            bstrURI,
            bstrName,
            NULL,
            VARIANT_TRUE,
            NULL,
            0,
            &pBuddy);

    SAFE_RELEASE(pPresence);

    if (FAILED(hr))
    {
        // Addbuddy が失敗しました。
        SAFE_RELEASE(pBuddy);
      char szBuf[256];

      wsprintf (szBuf, "Failed to Add Buddy to List.\nErr = 0x%x ", hr );
      MessageBox ( szBuf );
        return hr;
    }

    // 友人一覧のエントリを更新します。
    UpdateBuddyList(pBuddy);
    SAFE_RELEASE(pBuddy);

新しい友人が作成されると、新規作成された Buddy オブジェクト上の IRTCBuddy インターフェイスへのポインタが AddBuddy() メソッドから返されます。クライアント アプリケーションは、IRTCBuddy インターフェイスを使用して、友人のメンバ (Presentity) URI、友人の名前、友人の状態、永続性の種類、および友人のプレゼンスに関連付けられている個人データを取得できます。

プロファイルを登録解除して無効にする

SIP サーバーからユーザーの登録を解除するには、IRTCClientProvisioning::DisableProfile() メソッドを呼び出します。DisableProfile() メソッドを呼び出した後は、必ずプロファイル オブジェクトを解放してください。

パフォーマンスのために最適化する

以前の記事「Microsoft Real-Time Communications API による豊富なクライアント通信機能の統合」では、サンプルの RTC アプリケーションを実行する際の CPU 使用率を示しました。Pentium 4 プロセッサベースのシステムでは、依然としてバックグラウンド タスク用に大きなヘッドルームが用意されています。ただし、そのアーキテクチャによってアプリケーションの応答性が阻害される可能性があります。この問題に対処するために、並行して稼働するスレッドを作成し、直ちに注目する必要のある他のアクティビティを処理します。Service Pack 1 (SP1) を適用した Windows XP が稼働するハイパースレッディング テクノロジ搭載の Pentium 4 プロセッサでマルチスレッド アプリケーションを実行すると、アプリケーションの応答性が著しく向上し、アプリケーションがマルチタスクをより効率よく処理できるようになります。

SP1 を適用した Windows XP は、ハイパースレッディング テクノロジ搭載の Pentium 4 プロセッサを 2 つの論理プロセッサとして検出するので、Windows XP では単一の論理 CPU に比べて 2 倍の量の作業を CPU に対してスケジューリングすることができます。

ms997616.rtc_enhancerichclient-real-timecomm-4(ja-jp,MSDN.10).jpg

図 4: ハイパースレッディング テクノロジが使用されている場合のサンプル UI (左) と使用されていない場合のサンプル UI (右)

図 4 は、PC で使用されている Pentium 4 プロセッサにハイパースレッディング テクノロジが搭載されている場合と搭載されていない場合とで、バックグラウンドでディスク クリーンアップ ユーティリティを実行したときに CPU 使用率がどのように変わるかを示しています。

まとめ

リアルタイム通信 (RTC) API を使用すると、通信が PC 間、PC と電話間、電話間のどれでも完全に機能する会議ツールおよびコラボレーション ツールを構築できます。以前の記事では、インスタント メッセージングとアプリケーション共有を使用してオーディオ/ビデオ会議アプリケーションをいかにすばやく開発できるかを実証しました。この記事では、コミュニティの作成および関係者が参加可能かどうかの状態の追跡ができるように、プレゼンス機能と友人一覧機能を組み込んでさらに性能を強化しました。広範な RTC API を Microsoft リアルタイム通信サーバーと組み合わせることで、洗練された効果的な企業通信ツールを構築し、サイトを越えてチームの生産性を高めることができます。

RTC API を使用して開発した通信アプリケーションを、ハイパースレッディング テクノロジを搭載し、SP1 を適用した Windows XP が稼動している Pentium 4 プロセッサで実行することで、複数のタスクを同時に実行する一方で、応答性に優れたより高レベルのピア通信能力を実現できます。

リソース

Intel(R) Developer Services (英語)

Intel Pentium 4 Processor with Hyper-Threading Technology (英語)

スレッディングに関するヒント (英語)

Microsoft Real-Time Communications API による豊富なクライアント通信機能の統合

Integrating Windows Real-Time Communications into Applications (英語)

Q&A: Instant Messaging Milestone for Real-Time Communications Strategy (英語)、Press Pass、Microsoft Corporation、2002 年 12 月

Next Stop, "Greenwich": Enterprise IM Takes Shape with Platform Roadmap (英語)、Press Pass、Microsoft Corporation、2002 年 10 月

Microsoft Platform SDK: Real-time Communications (RTC) Client (英語)

Microsoft Platform SDK: Real-time Communications: Sample XML Profiles (英語)