Version1:
RTC Version1中用于通信的主要对象包括Client、Sesssion、Participant对象。现场对象包括Buddy和Watcher对象。XML配置文件由Provisioning接口设置和删除,使用Profile对象从配置文件中获取信息。
Version2:
Version2新增加了BuddyGroup、Presence Device、User Search Query对象。
主要的客户端对象IRTCClient接口在RTC Version1中定义,调用CoCreateInstance创建,需要参数 。
CoCreateInstance是COM Plantform SDK的一个方法,用于创建某个类的单独的没有初始化的对象,并且给该对象分配一个特定的CLSID(Class identifier,GUID = {7a42ea29-a2b7-40c4-b091-f6f024aa89be})。当你想要在当前系统创建一个对象是才调用CoCreateInstance,如果需要在远端系统创建一个对象,则调用CoCreateInstanceEx。
STDAPI CoCreateInstance(
REFCLSID rclsid, //Class identifier (CLSID) of the object
LPUNKNOWN pUnkOuter, //Pointer to whether object is or isn't part
// of an aggregate
DWORD dwClsContext, //Context for running executable code
REFIID riid, //Reference to the identifier of the interface
LPVOID * ppv //Address of output variable that receives
// the interface pointer requested in riid
);
rclsid:和用于创建对象的数据、代码有关。
pUnkOuter:Null表示对象不属于任何集合,不是Null,则指向集合对象的Iunknown接口。
DwClsContext:管理新创建对象的代码所处的上下文,包含在集合CLSCTX中。
CLSCTX_INPROC_SERVER
The code that creates and manages objects of this class runs in the same process as the caller of the function specifying the class context.
CLSCTX_INPROC_HANDLER
The code that manages objects of this class is an in-process handler. This is a DLL that runs in the client process and implements client-side structures of this class when instances of the class are accessed remotely.
CLSCTX_LOCAL_SERVER
The EXE code that creates and manages objects of this class is loaded in a separate process space (runs on same machine but in a different process).
CLSCTX_REMOTE_SERVER
A remote machine context. The LocalServer32 or LocalService code that creates and manages objects of this class is run on a different machine.
#define CLSCTX_SERVER (CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)
#define CLSCTX_ALL (CLSCTX_INPROC_HANDLER | CLSCTX_SERVER)
riid:与对象交互的接口的标志符。
ppv:指针变量的地址,保存了riid中请求的接口指针。
注意:GUID是一个全局唯一标志符,128位,如:6B29FC40-CA47-1067-B31D-00DD010662DA
。可以通过__uuidof获取,__uuidof(expression)获取expression的GUID,表达式可以为类型、指针、实现、数组等。
Version2中的RTCClient2通过调用Client对象的QueryInterface方法获得,这样使得Client2可以继承Version1中的方法和接口。Client2还提供了一些新的接口和方法定义如何处理每种会话类型的呼叫,同时可以了解RTC当前版本以及音频、视频调节是否允许。
Version1中的客户端对象可以设置允许的会话类型,会话参数(音频/视频设备、音量、媒体类型等)。IRTCClient接口创建Session对象,然后要用到 IRTCClientPresence 和 IRTCClientProvisioning 接口。IRTCClient接口包含了一系列可用的方法和接口,如下所示:
HRESULT hr = S_OK;
// RTC Initialization
// Note: Use the apartment threaded model because
// RTC applications are not thread safe.
::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
// Create the RTC Client COM object.
IRTCClient *pIRTCClient;
hr = CoCreateInstance( CLSID_RTCClient,
NULL,
CLSCTX_INPROC_SERVER,
IID_IRTCClient,
reinterpret_cast<void **> (&pIRTCClient) );
// If (hr != S_OK), process the error here.
// Initialize the RTCClient interface.
hr = pIRTCClient->Initialize();
// If (hr != S_OK), process the error here.
BuddyGroup对象是将(以功能为目的的)好友划分为组的主要对象。IRTCBuddyGroup接口通过IRTCClientPresence2::AddGroup方法创建,每一个组都有名字和与之相关的XML SIP配置文件,该配置文件和其他的联系类型一样可以在SIP服务器间漫游。
通过IRTCBuddyGroup::AddBuddy在组内增加好友,或者通过IRTCBuddyGroup::RemoveBuddy删除好友。Version2中好友默认不属于任何组。组必须首先定义,然后将好友加入。添加好友或者组可以用IRTCClientPresence::AddBuddyEx或者IRTCClientPresence2::AddGroup,属于异步操作。程序必须等待RTCBET_BUDDY_ADD和RTCGET_GROUP_ADD事件以确保buddy和group对象成功创建,然后才可以调用IRTCBuddyGroup::AddBuddy将好友加至组中。
为了捕获到组变化的事件,需要在IRTCClient中加入时间过滤器RTCEF_GROUP。
查询用户对象可以定制查询条件,通过IRTCUserSearch::CreateQuery方法创建IRTCUserSearchQuery接口,在Version2中,查询作为RTC客户端的一部分很容易就可以实现,当CoCreateInsance创建一个RTC客户端对象时,IRTCUserSearch接口默认被创建,可以通过QueryInterface方法获取,参数为with IID_IRTCUserSearch (iid=B619882B-860C-4db4-BE1B-693B6505BBE5)。
IRTCUserSearch包含两个方法,CreateQuery创建一个查询对象,ExecuteSearch执行查询对象,返回结果,作为查询结果事件(RTCE_USERSEARCH)。ExecuteSearch参数中包含一个长整形的cookie,标志查询结果的唯一性。
查询条件由IRTCUserSearchQuery接口,通过put_SearchTerm,put_SearchDomain,put_SearchPreferences等设置,执行查询操作时,必须在ExecuteSearch对象参数中提供指向IRTCUserSearchQuery接口的指针。RTCE_USERSEARCH由事件处理机制处理(IRTCEventNotification),查询结果通过在事件处理的返回对象上调用QueryInterface得到IRTCUserSearchResultsEvent接口处理,包含以下方法:
查询结果包括列名和值,包含在IRTCUserSearchResult对象中,通过get_Value方法获取,参数为RTC_USER_SEARCH_COLUMN集合中列的值,该列的值作为返回值返回。
如果返回结果超过了服务器可用的最大值,IRTCUserSearchResultsEvent::get_MoreAvailable判断执行操作,或者重新查找,或者返回部分结果。
查询结果可以将RTCUSC_URI和RTCUSC_DISPLAYNAME传给bstrPresentityURI和bstrUserName参数,执行IRTCClientPresence2::AddBuddyEx方法,也可以增加新的Watcher,通过调用IRTCClientPresence2::AddWatcherEx方法。
现场设备对象获取现场信息,作为好友属性显示。包括状态、注释、现场属性和设备数据。IRTCPresenceDevice接口通过IRTCEnumPresenceDevices::Next方法获得。
Presence Devices?????
Session对象支持所有的会话类型(PC-PC,PC-phone,Phone-phone,IM,MIM,Application),代表了一个可以创建或者接受音频/视频呼叫或者IM会话的实体。会话信息,比如状态、媒体类型、共享信息也可以通过会话接口获取。AddParticipant方法创建Participant对象,初始化IM会话或者音频/视频呼叫。IRTCSession接口包含一系列方法,参见下面例子:
HRESULT hr = S_OK;
BSTR bstrLocalURI = NULL;
BSTR bstrDestURI = NULL;
RTC_SESSION_TYPE SessionType;
IRTCSession *pIRTCSession = NULL;
IRTCProfile *pIRTCProfile = NULL;
SessionType = // Specify session type
// For phone-phone sessions, the local telephone URI is required.
if (SessionType == RTCST_PHONE_TO_PHONE)
{
bstrLocalURI = SysAllocString(_T("tel:+14255550123"));
// Unlike other session types, a phone-phone session must have a
// valid profile. Developers should ensure that *pIRTCProfile
// points to a valid profile object.
pIRTCProfile = // Look at "Create and Enable a Profile" code example
}
// Get the URI to call; this can be a sip: or a tel: URI.
bstrDestURI = SysAllocString(_T("sip:[email protected]"));
// Create the session with the specified session type and local URI.
hr = pIRTCClient->CreateSession( SessionType,
bstrLocalURI,
pIRTCProfile,
RTCCS_FORCE_PROFILE,
&pIRTCSession );
// If (hr != S_OK), process the error here.
// The AddParticipant method sets the session into the active state
// and creates the IRTCParticipant interface.
IRTCParticipant *pIRTCParticipant;
hr = pIRTCSession->AddParticipant( bstrDestURI,
NULL,
&pIRTCParticipant );
// If (hr != S_OK), process the error here.
Version2中提供了IRTCSession2,在Session对象中调用QueryInterface获取,增加了一些方法,管理会话的同时为会话指定安全级别。
Participant对象展示了获取名字、URI、状态的接口,Participants加入会话,通过IRTCSession::AddParticipant方法实现。多方会话只有phone-phone模式或者IM session模式下可以。
IRTCParticipant接口提供了一系列可用方法,参见上面例子。
Buddy对象展示了如何保存和获取联系人信息。好友列表通过IRTCClientPresence::AddBuddy方法创建,IRTCBuddy接口中包含对应的方法。IRTCBuddy2接口可以在Buddy对象中通过QueryInterface方法创建,提供了新的方法可以刷新好友,获取组信息和现场配置。
Watcher对象同Buddy。
Profile对象展示了获取保存在配置文件中参数的接口。IRTCProfile接口中包含可用方法。IRTCProfile2接口在Profile接口中调用QueryInterface创建,增加新的方法,包括为配置文件设置验证方法和域。
Create and Enable a Profile:
IRTCClientProvisioning *pIRTCClientProvisioning = NULL;
IRTCProfile *pIRTCProfile = NULL;
BSTR bstrXMLProfile = // XML Blob referenced in different section
// Perform QI for the Provisioning interface.
hr = pIRTCClient->QueryInterface(IID_IRTCClientProvisioning,
reinterpret_cast<void **>(&pIRTCClientProvisioning);
// If (hr != S_OK), process the error here.
// Create the Profile object.
hr = pIRTCClientProvisioning->CreateProfile( bstrXMLProfile,
&pIRTCProfile );
// If (hr != S_OK), process the error here.
// Enable the Profile and Register.
hr = pIRTCClientProvisioning->EnableProfile( pIRTCProfile,
RTCRF_REGISTER_ALL);
// If (hr != S_OK), process the error here.
Create the Roaming Profile:
由IRTCClientProvisioning::GetProfile创建配置文件,与服务器异步。程序收到RTCE_PROFILE事件表示配置文件已经获取,IRTCEventNotification::Event方法返回IRTCProfileEvent接口(pEvent参数),IRTCProfileEvent::get_Profile方法包含了配置文件(ppProfile参数)。
HRESULT LogonWithRoaming(IRTCClient *pClient,
BSTR bstrUsername,
BSTR bstrPassword,
BSTR bstrURI,
BSTR bstrServername )
{
HRESULT hr = S_OK;
IRTCClientProvisioning2 *pProv2 = NULL;
long lCookie = 0;
// Query for the IRTCClientProvisioning2 interface.
hr = pClient->QueryInterface(IID_IRTCClientProvisioning2,
(LPVOID *)&pProv2);
// If (hr != S_OK), process the error here.
// Get the profile to use for roaming.
hr = pProv2->GetProfile(bstrUsername,
bstrPassword,
bstrURI,
bstrServername,
RTCTR_TCP,
lCookie);
// If (hr != S_OK), process the error here.
// Release the reference to the
// IRTCClientProvisioning2 interface.
if (pProv2)
{
pProv2->Release();
}
Return S_OK
}
Deregister and Disable a Profile:
hr = pIRTCClientProvisioning->DisableProfile(pIRTCProfile);
// If (hr != S_OK), process the error here.
Version3
1. IRTCParticipant2接口继承至IRTCParticipant,支持获取参与者的设备ID以及参与者是否属于联盟(federated),联盟是否保存即时消息。
2. IRTCPresenceDevice2继承至IRTCPresenceDevice,支持获取设备的ID。
3. IRTCSession3继承至IRTCSession2,支持对特定设备开始会话。
4. IRTCClient2接口保留,但IRTCClient2::InitializeEx方法增加两个标志用于丢弃没有验证的请求。
5. IRTCProfile3接口继承至IRTCProfile2,增加了一个方法获取配置文件的注册地址。
IRTCProtManager2接口继承至IRTCPortManager接口。除了UpdateRemoteAddress指定的信息外,增加了UpdateRemoteAddressEx方法指定远端端口。