realvod.cpp
来自「本人买的<<VC++项目开发实例>>源代码配套光盘.」· C++ 代码 · 共 1,090 行 · 第 1/3 页
CPP
1,090 行
/****************************************************************************
*
* $Id: exallow.cpp,v 1.1 1998/12/03 18:44:43 darrens Exp $
*
* Copyright (C) 1998 RealNetworks, Inc.
* All rights reserved.
*
* http://www.real.com/devzone
*
* This program contains proprietary information of RealNetworks, Inc.,
* and is licensed subject to restrictions on use and distribution.
*
* exallow.cpp
*
* Example Allowance plug-in for the RealMedia Architecture (RMA).
*/
/****************************************************************************
* This is an example of an Allowance plug-in. The purpose of an Allowance
* server plug-in is to monitor player connections to the server and make
* decisions about what each player is allowed to do. The Allowance plug-in
* receives a notification for each significant event in a player's
* connection lifetime, and can act to restrict the player's rights after
* receiving any one of these notifications. The ways in which an Allowance
* plug-in can restrict a player are varied, and include disconnecting,
* redirecting, authenticating, or granting limited permissions to the
* player in terms of which content can be played.
*
* In order for your plug-in to achieve this functionality, it must
* implement the IRMAPlayerConnectionAdviseSink interface which has
* methods for receiving notifications of many events in the course of
* each player connection. The IRMAPlugin interface must also be
* implemented to handle fundamental plug-in operations.
*
*
* Example: exallow.cpp
*
* This example demonstrates a simple Allowance Plug-in. It will impose the
* following two restrictions upon incoming player connections, to
* demonstrate just a few of the ways in which Allowance Plug-ins can be
* used to customize and extend the capabilities of the RMA server:
*
* 1) A maximum of 5 players will be allowed to view the
* rtsp://server:port/limited.rm URL at any given time. If a player
* requests this URL while 5 players are already viewing it, the 6th
* player will receive an alert message, asking them to try again later.
*
* 2) A player attempting to view the rtsp://server:port/jukebox.rm URL
* will be randomly redirected to one of the following URLs:
*
* - rtsp://server:port/song1.rm
* - rtsp://server:port/song2.rm
* - rtsp://server:port/song3.rm
*
* To test this example plug-in, simply build the plug-in, place it in
* your RMA server plug-in directory, and place RealMedia (.rm) files in
* your content directory with the names mentioned above (limited.rm,
* song1.rm, song2.rm, and song3.rm). Connect to one of the two special URLs
* with a RealPlayer to verify that the Allowance plug-in is working
* properly.
*
*
* The RMA server calls the various interface routines at well defined times.
* The sequence of the major events is as follows:
*
* Upon RMA server startup:
* - RMACreateInstance() creates new instance of CMyExampleRenderer class
* - GetPlugInInfo() returns descriptive information about the plug-in
*
* When a player first connects to the server:
* - OnConnection() called when a player connects
* - SetPlayerController() called to provide a player controlling interface
* - SetRegistryID() called to provide the location of player info.
* - OnURL() called when the player requests a URL
*
* During the player's connection:
* - OnBegin() called when player starts or resumes
* - OnStop() called when player stops
* - OnPause() called when the playback is paused
* - OnDone() called when the player has disconnected
*
*
* Note:
* The routines are listed roughly in the order in which they are called.
*/
/****************************************************************************
* Defines
*/
#define INITGUID /* Interface ID's */
#define MAX_LIMITED_URL_COUNT 5
#define LIMITED_URL_ALERT "Too many users are viewing this stream. Please try again later."
//UDP正在读取中。
#define PNR_READ_PENDING MAKE_HRESULT(0,SS_GLO,0x7)
#define PNR_READ_BILLING_PENDING MAKE_HRESULT(0,SS_GLO,0x11)
/****************************************************************************
* Includes
*/
#include <stdio.h> /* printf, sprintf */
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "dotnet.h"
#include "pntypes.h"
#include "pncom.h" /* IUnknown */
#include "rmacomm.h" /* IRMACommonClassFactory */
#include "rmapckts.h" /* IRMABuffer, IRMAPacket, IRMAValues */
#include "rmaplugn.h" /* IRMAPlugin */
#include "rmaallow.h" /* IRMAPlayerConnectionAdviseSink */
#include "rmamon.h" /* IRMAPNRegistry */
#include "rmafiles.h" /* IRMARequest */
#include "rmaerror.h" /* IRMAErrorMessages */
#include "realVOD.h" /* CExampleAllowance */
//检查变量,用于do{...}while(false);结构。
#define CHECK_VALUE_AND_BREAK(x) if (!(x)) \
{\
break; \
}
//构造IP地址,地址是按照本地字节顺序组织的4字节整数。
inline ULONG32 IPv4(UINT8 Ip1, UINT8 Ip2, UINT8 Ip3, UINT8 Ip4)
{
return (Ip4 + ((UINT32)Ip3 << 8) + ((UINT32)Ip2 << 16) + ((UINT32)Ip1 << 24));
}
/****************************************************************************
* RMACreateInstance ref: rmaplugn.h
*
* This routine creates a new instance of the CExampleAllowance class.
* It is called when the RMA server application is launched.
*/
STDAPI
RMACreateInstance(IUnknown** ppExAllowanceObj)
{
*ppExAllowanceObj = (IUnknown*)(IRMAPlugin*)new CExampleAllowance();
if (*ppExAllowanceObj != NULL)
{
(*ppExAllowanceObj)->AddRef();
return PNR_OK;
}
return PNR_OUTOFMEMORY;
}
/****************************************************************************
* CExampleAllowance static variables ref: exallow.h
*
* These variables are passed to the RMA server to provide information about
* this plug-in. They are required to be static in order to remain valid
* for the lifetime of the plug-in.
*/
const char* CExampleAllowance::zm_pDescription = MY_DESCRIPTION;
const char* CExampleAllowance::zm_pCopyright = MY_COPYRIGHT;
const char* CExampleAllowance::zm_pMoreInfoURL = MY_MORE_INFO_URL;
/****************************************************************************
* CExampleAllowance::CExampleAllowance ref: exallow.h
*
* Constructor
*/
CExampleAllowance::CExampleAllowance(void)
: m_RefCount (0),
m_pClassFactory (NULL),
m_pRegistry (NULL),
m_pPCResponse (NULL),
m_pPlayerController (NULL),
m_ulPlayerRegistryID (0),
m_pPlayerRegistryName (NULL),
m_bViewingLimitedURL (FALSE),
m_pNetworkServices (NULL) //初始化变量
, m_uCallbackInterval (1000)//(3 * 60 * 1000) //3分钟中断
, m_hCallback (NULL)
, m_pScheduler (NULL)
, m_stsStatus (statusNormal)
, m_pError (NULL) //初始化变量
, m_pUDPSocket (NULL)
, m_pUDPDataBuffer (NULL)
, m_bIsCommercial (false) //设置当前为访问不受保护资源
, m_bWaitingBillingResp (false) //是否正在等待计费的返回标志
{
fprintf(stdout, "Entering CExampleAllowance()...\n");
memset(m_szPassword, 0, sizeof(m_szPassword));
memset(m_szUserName, 0, sizeof(m_szUserName));
}
/****************************************************************************
* IRMAPlugin::GetPluginInfo ref: rmaplugn.h
*
* This routine returns descriptive information about the plug-in. It is
* called when the RMA server application is launched.
*/
STDMETHODIMP
CExampleAllowance::GetPluginInfo
(
REF(BOOL) bLoadMultiple,
REF(const char*) pDescription,
REF(const char*) pCopyright,
REF(const char*) pMoreInfoURL,
REF(UINT32) versionNumber
)
{
bLoadMultiple = TRUE;
pDescription = zm_pDescription;
pCopyright = zm_pCopyright;
pMoreInfoURL = zm_pMoreInfoURL;
versionNumber = MY_PLUGIN_VERSION;
return PNR_OK;
}
/****************************************************************************
* IRMAPlugin::InitPlugin ref: rmaplugn.h
*
* This routine performs initialization steps such as determining if
* required interfaces are available. It is called when the RMA core
* application is launched, and whenever a new player Allowance object
* is needed.
*/
STDMETHODIMP
CExampleAllowance::InitPlugin(IUnknown* pContext)
{
fprintf(stdout, "初始化InitPlugin()\n");
m_bWaitingBillingResp = false;
/*
* Store a reference to the IRMACommonClassFactory interface which is
* used to create commonly used RMA objects such as IRMAPacket,
* IRMAValues, and IRMABuffers.
*/
PN_RESULT hResult = PNR_FAILED;
do
{
hResult = pContext->QueryInterface(IID_IRMACommonClassFactory,
(void**)&m_pClassFactory);
CHECK_VALUE_AND_BREAK(m_pClassFactory)
/*
* Store a reference to the IRMAPNRegistry interface which is
* used to retrieve useful information about the connected player
*/
hResult = pContext->QueryInterface(IID_IRMAPNRegistry,
(void**)&m_pRegistry);
CHECK_VALUE_AND_BREAK(m_pRegistry);
//取得关键字路径
IRMABuffer *pPropertyValue = NULL;
const char *szBasePath = "config.VicAliPlugin.Commercial.KeyWord";
char pathKey[1024] = {0};
int i = 0;
sprintf(pathKey, "%s%d", szBasePath, i);
m_pRegistry->GetStrByName(pathKey, pPropertyValue);
while(pPropertyValue)
{
m_vectorProtectedDir.push_back((char *)pPropertyValue->GetBuffer());
PN_RELEASE(pPropertyValue);
sprintf(pathKey, "%s%d", szBasePath, ++i);
m_pRegistry->GetStrByName(pathKey, pPropertyValue);
}
for (m_theIterator = m_vectorProtectedDir.begin()
; m_theIterator != m_vectorProtectedDir.end()
; m_theIterator++)
{
fprintf(stdout, "Keyword--->%s\n", m_theIterator->c_str());
}
//取得IRMANetworkServices
hResult = pContext->QueryInterface(IID_IRMANetworkServices
,(void **)&m_pNetworkServices);
CHECK_VALUE_AND_BREAK(m_pNetworkServices);
//取得IRMAScheduler
hResult = pContext->QueryInterface(IID_IRMAScheduler
, (void **)&m_pScheduler);
CHECK_VALUE_AND_BREAK(m_pScheduler);
//取得IRMANetworkServices
hResult = pContext->QueryInterface(IID_IRMAErrorMessages
,(void **)&m_pError);
CHECK_VALUE_AND_BREAK(m_pError);
//创建UDP Socket
hResult = m_pNetworkServices->CreateUDPSocket(&m_pUDPSocket);
if (NULL == m_pUDPSocket)
{
fprintf(stdout, "CreateUDPSocket fail.\n");
break;
}
else
{
fprintf(stdout, "CreateUDPSocket successfully.\n");
}
hResult = m_pUDPSocket->Init(IPv4(127, 0, 0, 1)/*127.0.0.1*/, 0, this);
CHECK_VALUE_AND_BREAK(hResult);
/*
* Note that QueryInterface() takes care of adding a reference to the
* interface for us. You are however responsible for releasing the
* reference to the object when you are done using it by calling
* the Release() routine.
*/
}while(false);
return hResult;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::OnConnection ref: rmaallow.h
*
* The server core calls this routine when a new player has connected
* to the server.
*/
STDMETHODIMP
CExampleAllowance::OnConnection(THIS_ IRMAPlayerConnectionResponse* pResponse)
{
m_pPCResponse = pResponse;
m_pPCResponse->AddRef();
m_pPCResponse->OnConnectionDone(PNR_OK);
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::SetPlayerController ref: rmaallow.h
*
* The server core calls this routine to supply the Allowance plug-in with
* an interface by which the player can be controlled. For example, this
* interface can be used to disconnect the player, send them an alert
* message, or redirect them to another URL.
*/
STDMETHODIMP
CExampleAllowance::SetPlayerController(THIS_
IRMAPlayerController* pPlayerController)
{
m_pPlayerController = pPlayerController;
m_pPlayerController->AddRef();
return PNR_OK;
}
/****************************************************************************
* IRMAPlayerConnectionAdviseSink::SetRegistryID ref: rmaallow.h
*
* The server core calls this routine to supply the Allowance plug-in with
* a server registry ID, which can be used to find out various pieces of
* information about the connected player. For example, the player's IP
* Address, GUID, and Protocol are all stored under this key in the server
* registry.
*/
STDMETHODIMP
CExampleAllowance::SetRegistryID(THIS_ UINT32 ulPlayerRegistryID)
{
m_ulPlayerRegistryID = ulPlayerRegistryID;
// Obtain the name of the key for obtaining subkeys later
m_pRegistry->GetPropName(ulPlayerRegistryID, m_pPlayerRegistryName);
return PNR_OK;
}
/****************************************************************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?