realvod.cpp
来自「本人买的<<VC++项目开发实例>>源代码配套光盘.」· C++ 代码 · 共 1,090 行 · 第 1/3 页
CPP
1,090 行
* IRMAPlayerConnectionAdviseSink::OnURL ref: rmaallow.h
*
* The server core calls this routine when the connected player requests
* a URL. The requested URL is stored in the passed IRMARequest object,
* along with all 822 Headers that accompanied the request.
*/
STDMETHODIMP
CExampleAllowance::OnURL(THIS_ IRMARequest* pRequest)
{
PN_RESULT hResult = PNR_OK;
const char* pURL = NULL;
//从Cookie中取得用户名和密码
IRMAValues *pIRMAValues = NULL;
pRequest->GetRequestHeaders(pIRMAValues);
IRMABuffer *pPropertyValue = NULL;
if (pIRMAValues != NULL)
{
//取得Cookie
hResult = pIRMAValues->GetPropertyCString(
"Cookie", pPropertyValue);
//得到用户名字和密码
GetUserInfoFromCookie((const char *)pPropertyValue->GetBuffer());
PN_RELEASE(pPropertyValue);
PN_RELEASE(pIRMAValues);
}
// Obtain the requested URL
pRequest->GetURL(pURL);
for (m_theIterator = m_vectorProtectedDir.begin()
; m_theIterator != m_vectorProtectedDir.end()
; m_theIterator++)
{
if (strstr(pURL, m_theIterator->c_str()))
{
//设置当前的状态为访问受保护的资源。
m_bIsCommercial = true;
hResult = HandleProtectedURLRequest();
break;
}
}
if (!strcmp(pURL, "limited.rm"))
{
// The player requested the limited.rm URL
hResult = HandleLimitedURLRequest();
}
else if (!strcmp(pURL, "jukebox.rm"))
{
// The player requested the jukebox.rm URL
hResult = HandleJukeboxURLRequest();
}
/*
* Note: Most IRMAPlayerConnectionAdviseSink interface functions have
* a corresponding response function in the IRMAPlayerConnectionResponse
* interface. This function should be called when the plug-in has
* finished processing the notification.
*
* The connected player will not be permitted to begin playback until
* all allowance plugins have called OnURLDone() with a Status of PNR_OK.
*/
if (PNR_READ_PENDING == hResult)
{
//必须等待授权的结果,所以不能
//调用m_nPCResponse->OnURLDone(hResult);
//调用OnURLDone()的任务在ReadDone中完成。
//设置CallBack
m_hCallback = m_pScheduler->RelativeEnter(this
, 1000 * 100/*100秒钟*/);
if (m_hCallback)
{
fprintf(stdout, "加入OnAuthenticationTimeout成功\n");
}
else
{
fprintf(stdout, "加入OnAuthenticationTimeout功能失败!!\n");
}
}
else
{
m_pPCResponse->OnURLDone(hResult);
}
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::OnBegin ref: rmaallow.h
*
* The server core calls this routine when the player begins or resumes
* playback.
*/
STDMETHODIMP
CExampleAllowance::OnBegin(void)
{
m_stsStatus = statusNormal;
if (m_bIsCommercial)
{
//设置CallBack
m_hCallback = m_pScheduler->RelativeEnter(this, m_uCallbackInterval);
if (m_hCallback)
{
fprintf(stdout, "加入HeartBeating功能\n");
}
else
{
fprintf(stdout, "加入HeartBeating功能失败!!\n");
}
m_stsStatus = statusHeartbeating;
}
m_pPCResponse->OnBeginDone(PNR_OK);
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::OnPause ref: rmaallow.h
*
* The server core calls this routine when the player pauses playback.
*/
STDMETHODIMP
CExampleAllowance::OnPause(void)
{
m_pPCResponse->OnPauseDone(PNR_OK);
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::OnStop ref: rmaallow.h
*
* The server core calls this routine when the player stops playback.
*/
STDMETHODIMP
CExampleAllowance::OnStop(void)
{
m_bWaitingBillingResp = false;
//移除CallBack
if (m_hCallback)
{
fprintf(stdout, "移除Scheduler\n");
m_pScheduler->Remove(m_hCallback);
m_hCallback = NULL;
}
PN_RELEASE(m_pUDPSocket); //Cancel Read operation
m_vectorProtectedDir.clear();
if (m_bViewingLimitedURL)
{
// This player has finished viewing the "limited.rm" URL
DecrementLimitedURLCount();
m_bViewingLimitedURL = FALSE;
}
m_pPCResponse->OnStopDone(PNR_OK);
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::OnDone ref: rmaallow.h
*
* The server core calls this routine when the player has disconnected
* from the server.
*
*/
STDMETHODIMP
CExampleAllowance::OnDone(void)
{
return PNR_OK;
}
/****************************************************************************
* CExampleAllowance::~CExampleAllowance ref: exallow.h
*
* Destructor
*/
CExampleAllowance::~CExampleAllowance(void)
{
fprintf(stdout, "Entering ~CExampleAllowance()...\n");
PN_RELEASE(m_pClassFactory);
PN_RELEASE(m_pRegistry);
PN_RELEASE(m_pPCResponse);
PN_RELEASE(m_pPlayerController);
PN_RELEASE(m_pPlayerRegistryName);
PN_RELEASE(m_pNetworkServices);
//释放IRMAScheduler
PN_RELEASE(m_pScheduler);
//释放IRMAErrorMessages
PN_RELEASE(m_pError);
PN_RELEASE(m_pUDPSocket);
PN_RELEASE(m_pUDPDataBuffer);
}
// IUnknown COM Interface Methods
/****************************************************************************
* IUnknown::AddRef ref: pncom.h
*
* This routine increases the object reference count in a thread safe
* manner. The reference count is used to manage the lifetime of an object.
* This method must be explicitly called by the user whenever a new
* reference to an object is used.
*/
STDMETHODIMP_(UINT32)
CExampleAllowance::AddRef(void)
{
return InterlockedIncrement(&m_RefCount);
}
/****************************************************************************
* IUnknown::Release ref: pncom.h
*
* This routine decreases the object reference count in a thread safe
* manner, and deletes the object if no more references to it exist. It must
* be called explicitly by the user whenever an object is no longer needed.
*/
STDMETHODIMP_(UINT32)
CExampleAllowance::Release(void)
{
if (InterlockedDecrement(&m_RefCount) > 0)
{
return m_RefCount;
}
delete this;
return 0;
}
/****************************************************************************
* IUnknown::QueryInterface ref: pncom.h
*
* This routine indicates which interfaces this object supports. If a given
* interface is supported, the object's reference count is incremented, and
* a reference to that interface is returned. Otherwise a NULL object and
* error code are returned. This method is called by other objects to
* discover the functionality of this object.
*/
STDMETHODIMP
CExampleAllowance::QueryInterface
(
REFIID interfaceID,
void** ppInterfaceObj
)
{
// By definition all COM objects support the IUnknown interface
if (IsEqualIID(interfaceID, IID_IUnknown))
{
AddRef();
*ppInterfaceObj = (IUnknown*)(IRMAPlugin*)this;
return PNR_OK;
}
// IRMAPlugin interface is supported
else if (IsEqualIID(interfaceID, IID_IRMAPlugin))
{
AddRef();
*ppInterfaceObj = (IRMAPlugin*)this;
return PNR_OK;
}
// IRMAPlayerConnectionAdviseSink interface is supported
else if (IsEqualIID(interfaceID, IID_IRMAPlayerConnectionAdviseSink))
{
AddRef();
*ppInterfaceObj = (IRMAPlayerConnectionAdviseSink*)this;
return PNR_OK;
}
// No other interfaces are supported
*ppInterfaceObj = NULL;
return PNR_NOINTERFACE;
}
PN_RESULT
CExampleAllowance::HandleLimitedURLRequest()
{
PN_RESULT hResult = PNR_OK;
INT32 nClientCount = 0;
IRMABuffer* pBuffer = NULL;
// Find out how many players are currently watching this URL
if (PNR_OK != m_pRegistry->GetIntByName("server.LimitedURLCount",
nClientCount))
{
// The registry item does not exist yet, so create it
nClientCount = 0;
m_pRegistry->AddInt("server.LimitedURLCount", nClientCount);
}
// Test the limit, to determine if it has reached capacity
if (nClientCount >= MAX_LIMITED_URL_COUNT)
{
// We have reached capacity, so send them an alert message
m_pClassFactory->CreateInstance(CLSID_IRMABuffer, (void**)&pBuffer);
pBuffer->Set((const UCHAR*)LIMITED_URL_ALERT,
strlen(LIMITED_URL_ALERT) + 1);
m_pPlayerController->AlertAndDisconnect(pBuffer);
PN_RELEASE(pBuffer);
hResult = PNR_FAIL;
}
else
{
// We have not reached capacity, so let them have access
m_bViewingLimitedURL = TRUE;
// Increment the count and update its registry value
nClientCount++;
m_pRegistry->SetIntByName("server.LimitedURLCount", nClientCount);
}
return hResult;
}
PN_RESULT
CExampleAllowance::HandleJukeboxURLRequest()
{
UINT32 ulRand = 0;
char pNewURL[256];
IRMABuffer* pBuffer = NULL;
// Generate a random number between 0 and 2
srand((unsigned)time(NULL));
ulRand = rand() % 3;
// Choose a redirect URL based on the result
switch(ulRand)
{
case 0:
{
sprintf(pNewURL, "song1.rm");
}
break;
case 1:
{
sprintf(pNewURL, "song2.rm");
}
break;
case 2:
default:
{
sprintf(pNewURL, "song3.rm");
}
break;
}
// Redirect the player
m_pClassFactory->CreateInstance(CLSID_IRMABuffer, (void**)&pBuffer);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?