精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
QTSS对象是由用于存储数据的属性组成的。每个属性都有一个名称,一个属性ID,一个数据类型,以及一个用于控制读写属性值的权限。有两种属性类型:
请注意:添加静态属性的效率要比添加实例属性高,因此我们强烈推荐添加静态属性,而不是实例属性。
模块通过存储在对象中的属性来和服务器交换信息,因此会经常读取属性的值。有三个回调例程可以用于获取属性值:
列表 2-1中的实例代码调用QTSS_GetValue函数来获取qtssRTPSvrCurConn属性的值,这个属性属于QTSS_ServerObject object对象,是一个非抢占访问安全的属性。
Listing 2-1 Getting the value of an attribute by calling QTSS_GetValue UInt32 MyGetNumCurrentConnections(QTSS_ServerObject inServerObject) { // qtssRTPSvrCurConn is a UInt32, so provide a UInt32 for the result. UInt32 theNumConnections = 0; // Pass in the size of the attribute value. UInt32 theLength = sizeof(theNumConnections); // Retrieve the value. QTSS_Error theErr = QTSS_GetValue(inServerObject, qtssRTPSvrCurConn, 0, &theNumConnections, &theLength); // Check for errors. If the length is not what was expected, return 0. if ((theErr != QTSS_NoErr) || (theLength != sizeof(theNumConnections)) return 0; return theNumConnections; } |
|
列表 2-2调用了QTSS_GetValuePtr函数,这是获取抢占访问安全的属性的推荐方法。在这个实例中,qtssRTSPReqMethod属性的值从QTSS_RTSPRequestObject对象中得到。
Listing 2-2 Getting the value of an attribute by calling QTSS_GetValuePtr QTSS_RTSPMethod MyGetRTSPRequestMethod(QTSS_RTSPRequestObject inRTSPRequestObject) { QTSS_RTSPMethod* theMethod = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inRTSPRequestObject, qtssRTSPReqMethod, 0, (void**)&theMethod, &theLen); if ((theErr != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod)) return -1; // Return a -1 if there is an error, which is not a valid // QTSS_RTSPMethod index else return *theMethod; } |
|
您可以通过调用QTSS_GetValueAsString函数来获取任何属性的值,该函数将属性值处理为一个C字符串。当您不知道属性包含的数据的类型时,调用QTSS_GetValueAsString 函数是非常便利的。
在列表 2-3中,qtssRTPSvrCurConn属性值从QTSS_ServerObject对象得到,并处理为字符串。
Listing 2-3 Getting the value of an attribute by calling QTSS_GetValueAsString void MyPrintNumCurrentConnections(QTSS_ServerObject inServerObject) { // Provide a string pointer for the result char* theCurConnString = NULL; // Retrieve the value as a string. QTSS_Error theErr = QTSS_GetValueAsString(inServerObject, qtssRTPSvrCurConn, 0, &theCurConnString); if (theErr != QTSS_NoErr) return; // Print out the result. Because the value was returned as a string, use // %s in the printf format. ::printf("Number of currently connected clients: %s\n", theCurConnString); // QTSS_GetValueAsString allocates memory, so reclaim the memory by calling QTSS_Delete. QTSS_Delete(theCurConnString); } |
|
有两个QTSS回调函数可用于设定属性的值:QTSS_SetValue和QTSS_SetValuePtr。
列表2-4中的实例代码在处理Route角色的地方可以找到。代码中调用QTSS_GetValuePtr函数来获取qtssRTSPReqFilePath属性的值。如果获得的路径和特定的字符串相匹配,则调用QTSS_SetValue函数来将qtssRTSPReqRootDir属性设置为新的路径,从而为请求设定一个新的根路径。
Listing 2-4 Setting the value of an attribute by calling QTSS_SetValue // First get the file path for this request using QTSS_GetValuePtr char* theFilePath = NULL; UInt32 theFilePathLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqFilePath, 0, &theFilePath, &theFilePathLen); // Check for any errors if (theErr != QTSS_NoErr) return; // See if this path is a match. If it is, use QTSS_SetValue to set the root directory for this request. if ((theFilePathLen == sStaticFilePathLen) && (::strncmp(theFilePath, sStaticFilePath, theFilePathLen) == 0)) { theErr = QTS_SetValue(inParams->inRTSPRequest, qtssRTSPReqRootDir, 0, sNewRootDirString, sNewRootDirStringLen); if (theErr != QTSS_NoErr) return; } |
|
列表 2-5演示了如何使用QTSS_SetValuePtr回调函数。QTSS_SetValuePtr函数将一个属性和一个模块变量的值进行关联。这个例子代码的目的是以非原子的形式对QTSS_ServerObject对象进行修改,因此调用QTSS_LockObject函数来避免其它线程在QTSS_ServerObject对象的属性值设定完成之前访问该属性。
接着调用QTSS_CreateObjectValue函数来创建一个QTSS_ConnectedUserObject对象,以便给QTSS_ServerObject对象的qtssSvrConnectedUsers属性赋值。然后,再调用QTSS_SetValuePtr函数,将QTSS_ConnectedUserObject对象的qtssConnectionBytesSent属性设定为模块的fBytesSent变量。在此之后,任何模块获取qtssConnectionBytesSent属性值的时候,得到的是模块的fBytesSent v变量的当前值。
在QTSS_SetValuePtr函数之后,代码就调用QTSS_UnlockObject函数,来解锁QTSS_ServerObject对象。
Listing 2-5 Setting the value of an attribute by calling QTSS_SetValuePtr UInt32 index; QTSS_LockObject(sServer); QTSS_CreateObjectValue(sServer, qtssSvrConnectedUsers, qtssConnectedUserTypeObject, &index, &fQTSSObject); QTSS_CreateObjectValue(sServer, qtssSvrConnectedUsers, qtssConnectedUserObjectType, &index, &fQTSSObject); QTSS_SetValuePtr(fQTSSObject, qtssConnectionBytesSent, &fBytesSent, sizeof(fBytesSent)); QTSS_UnlockObject(sServer); |
|
模块可以在Register角色中调用QTSS_AddStaticAttribute回调函数,来将一个属性添加到QTSS对象中去;还可以在任何角色中调用QTSS_AddInstanceAttribute函数,想对象的实例添加属性。
请注意:向对象类型或者对象实例中添加一个或者多个属性,是模块存储专用与某个特定会话的最有效和推荐的方法。
一旦添加完成,新属性就会被包含在由服务器创建的每一个相应类型的对象中,而且它的值也可以调用如下与操作服务器内置属性相同的方法来进行设置和获取:QTSS_SetValue,QTSS_SetValuePtr,QTSS_GetValue,和QTSS_GetValuePtr.
请注意:如果要往您自己创建的模块中添加属性,则必须首先调用QTSS_LockObject函数来锁定对象,在所有属性添加完成之后,调用QTSS_UnlockObject 函数来解锁对象。
列表 2-6中的实例代码调用QTSS_AddStaticAttribute函数来往QTSS_ClientSessionObject对象中添加属性:
Listing 2-6 Adding a static attribute QTSS_Error MyRegisterRoleFunction() { // Add the static attribute. The third parameter is always NULL. QTSS_Error theErr = QTSS_AddStaticAttribute(qtssClientSessionObjectType, |
请注意:添加了的属性(静态属性或者实例属性)的属性权限会被自动设置为可读,可写,和抢占访问安全。