Previous | Next |
This section discusses in detail the interaction between the client, the server running Windows Media Services, and the authorizer component.
The following topics are covered in this section:
When started, the server queries the system registry for all installed event notification and authorization plug-in components. If startup succeeds, the server retrieves the class identifier (CLSID) of the plug-in components and creates instances of the plug-in components. Then the server calls the INSSEventNotification::Initialize method of each component to initialize the instantiated objects, passing in a pointer to the server context. This context object contains properties describing certain attributes of the server. These properties include, but are not limited to:
The server context object is available as long as the server is running. Later, the server can pass additional contexts into a component, such as a user context or a presentation context.
Note During the server startup, the Initialize() method is always called on all event notification and authorization plug–in components that have been configured in the server. This method call happens even if the plug-in component is disabled. As a consequence, if any disabled plug-in returns a failure code on the Initialize() method call, the server still starts up, but without the necessary information for performing an authorization task, it cannot stream.
A heartbeat can be used by a plug-in for timing other events and for monitoring the operational state of the server. You can have the server enable the heartbeat by specifying a positive value for the dwMsHeartbeatPeriod parameter and passing it back to the server in the Initialize method of the INSSEventNotification interface. If a heartbeat is enabled, the server calls the INSSEventNotification::OnHeartBeat method at the regular intervals of the specified heartbeat period. Setting the dwMsHeartbeatPeriod parameter to 0 (zero) disables the heartbeat.
After initialization, the server calls the INSSEventNotification::GetHandledEvents method of each component. This method is used to specify which events trigger a call to the event handler by the server. The following types of events are supported for notification:
After notification events are set, the server calls the QueryInterface method of the INSSEventAuthorization interface to determine whether the authorization interface is supported. All components must implement the INSSEventNotification interface. However, implementing the INSSEventAuthorization interface is optional. When authorization is supported, the server invokes the INSSEventAuthorization::GetAuthorizedEvents method to retrieve the array of authorized events, and thus determines which events require authorization.
A component specifies which event must be authorized. You implement the scheme with the INSSEventAuthorization::GetAuthorizedEvents method. This method is similar to that of specifying the events for notification. However, fewer events are supported for authorization. For instance, requiring authorization from the server before the client disconnects is not useful because the server cannot prevent a client from disconnecting.
You can specify the following events for authorization:
The server running Windows Media Services calls the INSSEventAuthorization::AuthorizeEvent method to determine whether it performs the task associated with an event that requires authorization. When calling the method, the server supplies the component with information about the event, client, and content to be authorized.
If the authorization is a complicated and lengthy process, implement the AuthorizeEvent method asynchronously, spawning another thread to determine if the request must be granted. Asynchronous implementation results in an immediate return of calls to the method, and frees the server to proceed with other tasks while the authorization is in progress. However, if the authorization is simple, the method must return synchronously; that is, it must return a call after the authorization is finished.
At the end of the authorization process, whether the request is granted or denied, the authorization component makes a call to the server to invoke the INSSEventAuthorizationCallback::OnEventAuthorized method. A pointer to the INSSEventAuthorizationCallback interface is passed in by the server when it invokes the AuthorizeEvent method. The authorization component must call this method, whether the AuthorizeEvent method returns synchronously or asynchronously. However, if the call to AuthorizeEvent method fails, no call back happens.
To uniquely identify the event requested for authorization, both the server and the authorization component pass the dwRequestId parameter to each other. The server passes the parameter into the component through the call to the INSSEventAuthorization::AuthorizeEvent method. The authorization component must pass the same request identifier back to the server through the call to the INSSEventAuthorizationCallback::OnEventAuthorized method.
Authorization can also be performed using data dynamically generated at runtime. The client can pass additional information otherwise unavailable at run time to the authorizer by appending a string containing the data to the Uniform Resource Locator (URL) of the source stream. The server ignores all of the characters after the question mark (?) when it resolves the URL and determines which file to stream to the client. However, the string is stored intact in the NSS_PRESENT_PHYSICAL_NAME property of the Presentation Context. The authorization component is responsible for parsing this string.
For example, a user wants to watch a title called TrainingABC.asf on the local server. In a typical situation where an authorizer relies on a database for checking client credentials, the user opens the title by supplying the URL of the source file:
mms://localhost/TrainingABC.asf
On the other hand, the authorizer can choose not to use any database, but depend on the user to provide necessary information, such as name and employee identification, at run time. The user can do so by appending the information to the URL of the source stream, as illustrated in the following example:
mms://localhost/TrainingABC.asf?USER=Joe;ID=2316
If the title consists of, for example, three lessons—A, B, and C—you can write an authorizer to let the user choose and view a lesson:
mms://locahost/TrainingABC.asf?LESSON=B
The server also notifies the component of any events that are registered for notification by using the INSSEventNotification::GetHandledEvents method. The notification specifies the type of event requested and the results of the authorization, when applicable.
You can choose to implement different responses to the notification in the INSSEventNotification::OnEvent method. For example, you can gather the viewing statistics of the client when the user connects to the server. Alternatively, you can tally the charge incurred by the viewer when the title is stopped.
Suppose a user chooses to play a title, and one component has been registered for event notification and authorization. The server requests that the event notification and authorization component check on the user. When the user is authorized to play the title, the server then opens the title for the user. If the authorization fails, the server does not open the title. In either case, the server calls the INSSEventNotification::OnEvent method to notify the component whether the event is occurring (in this case, whether the title is being played). If authorization is not required, the server opens the title for the user, and then notifies the component that the title is being played.
When multiple components are registered and enabled, the server queries the components, one by one, to authorize the user. If all the components grant permission, the server allows the event to take place, and then notifies each component that it has.
If, however, any component denies the request, the server stops the query process at the first denial. The authorization fails, and the server does not enable the event. The server notifies all the consulted components through event notification that the event did not occur.
Note If you allow streaming using Hypertext Transfer Protocol (HTTP) on the server running the Windows Media Unicast service, a single client action, such as clicking the Play button, can result in multiple authorizations and notifications for Connect, Open, and Play events on the server. This is because, when HTTP is used, the client uses separate HTTP requests to retrieve the HEAD and the BODY of an Advanced Streaming Format (.asf) file. For the server, these are multiple requests. Your event notification and authorization component must be equipped to handle such cases appropriately. When HTTP is used instead of the MMS protocol, this HTTP-specific behavior makes it difficult, although not impossible, to implement an authorization scheme that does not overcharge the customer for viewing a title based on the number of times he or she attempts to open it.
The following diagram outlines the interaction between the server running Windows Media Services, an event notification and authorization plug-in component, and a client.
Previous | Next |