SIP 服务器注册
要启用出席信息服务,需要创建一个“配置文件”对象。配置文件对象是通过 IRTCClientProvisioning::CreateProfile 方法创建的。要创建配置文件对象,客户端应用程序需要创建一个符合装置架构的 XML 字符串。XML 架构的&&属性包括:
装置设置 - 配置文件的唯一标识符。
用户设置 - 用户的 URI、领域和登录帐户信息
客户端设置 - 有关与通信链路无关的客户端应用程序信息。此信息是可选的。
提供商设置 - 有关 Internet 电话服务提供商 (ITSP) 的信息。
SIP 服务器设置 - 指定可用的 SIP 服务器、SIP 服务器角色和服务器支持的会话类型。
要在 SIP 服务器上注册用户,客户端需要创建一个 XML 配置文件字符串,指示 RTC 客户端 API 如何与 SIP 服务器进行通信。创建 XML 字符串后,即可调用 IRTCClientProvisioning::CreateProfile() 方法创建一个配置文件对象。下一步是调用 IRTCClientProvisioning::EnableProfile() 方法在 RTC 服务器上注册用户,并指定配置文件应该在该服务器上注册的会话类型。注册类型可以是:允许传入计算机到计算机的会话 (RTCRF_REGISTER_INVITE_SESSIONS)、允许传入即时消息会话 (RTCRF_REGISTER_MESSAGE_SESSIONS)、允许传入观察程序 (RTCRF_REGISTER_PRESENCE) 或允许所有的注册类型 (RTCRF_REGISTER_ALL)。设置 RTCRF_REGISTER_PRESENCE 或 RTCRF_REGISTER_ALL 将通知注册服务器:客户端接受 SIP SUBSCRIBE 方法。这将允许用户通知其他用户他们的出席状态更改、获取其联系人出席状态更改的通知以及将出席信息添加到观察程序列表的其他人。
观察程序对象在好友列表中提供了用户状态。观察程序可以查询 Presentity 的状态,并得到好友列表中的用户状态更改的通知。观察程序还使用户能够通过 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;
}
// 启用出席信息
// 最好在启用配置文件之后立即启用出席信息,
// 这样传入的观察程序就不会丢失。
// 有关&&函数定义,请参阅以下 EnablePresence() 方法
hr = EnablePresence(TRUE);
if (FAILED(hr))
{
// DoEnablePresence 失败
DoSIPLogoff(); // 有关&&函数示例,请参阅代码示例 AVDConf2.exe
return hr;
}
return S_OK;
}
启用配置文件后,还应启用出席信息以防传入的观察程序&&事件丢失。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))
{
// 导出失败
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);
// 清理观察程序
IRTCEnumWatchers * pEnumWatcher = NULL;
IRTCWatcher * pWatcher = NULL;
hr = pPresence->EnumerateWatchers(&pEnumWatcher);
if (FAILED(hr))
{
// 枚举观察程序失败
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;
}
在 RTC 服务器中注册后,应用程序接收 RTCE_REGISTRATION_STATE_CHANGE &&事件,指示注册是完成还是失败。
出席信息服务可以在服务器注册您的配置文件之前启用。下图显示了注册前启用出席信息服务的方法。
这可以使用户在注册到服务器之前设置他们的状态。现在,用户可以注册到 SIP 服务器,而对观察程序可以显示为“离线”,并查看联系人状态。当用户要在不受干扰的情况下监视组的出席状态时,此功能非常有用。
图 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" />
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)<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="&&keyword=session&Submit=+%CB%D1%CB%F7+"session" minOccurs="0" maxOccurs="*" />
</ElementType>
<ElementType name="&&keyword=session&Submit=+%CB%D1%CB%F7+"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>