Filtrage des notifications et styles de communication
Cette section décrit l’interface entre le processus de spouleur et les composants d’impression tels que le processeur d’impression, le pilote et le moniteur.
Filtrage des notifications
Le type énuméré PrintAsyncNotifyUserFilter est utilisé pour deux situations. Dans le premier d’entre eux, un composant d’impression s’exécutant à l’intérieur du spouleur appelle la fonction CreatePrintAsyncNotifyChannel pour créer un canal de notification. L’appelant passe un énumérateur du type énuméré PrintAsyncNotifyUserFilter pour spécifier quels clients à l’écoute sont autorisés à recevoir des notifications. Dans la deuxième situation, un client à l’écoute appelle la fonction RegisterForPrintAsyncNotifications pour s’inscrire à la notification. L’appelant passe l’un des énumérateurs PrintAsyncNotifyUserFilter pour indiquer les notifications qu’il doit recevoir.
typedef enum
{
kPerUser,
kAllUsers
} PrintAsyncNotifyUserFilter;
Dans la figure qui suit, l’énumérateur kPerUser est utilisé dans l’appel à la fonction CreatePrintAsyncNotifyChannel . Par conséquent, seuls les écouteurs qui s’exécutent dans le même compte d’utilisateur que l’utilisateur qui a effectué l’inscription sont autorisés à recevoir des notifications.
Dans la figure suivante, l’énumérateur kAllUsers est utilisé dans l’appel à la fonction CreatePrintAsyncNotifyChannel . Par conséquent, tous les écouteurs intéressés par l’imprimante ou le serveur peuvent recevoir des notifications. Notez que seuls les administrateurs sont autorisés à utiliser le paramètre kAllUsers dans les appels à cette fonction.
La figure suivante montre la situation dans laquelle l’utilisateur 1 et l’utilisateur 2 se sont inscrits pour recevoir des notifications en appelant la fonction RegisterForPrintAsyncNotifications , en passant l’énumérateur kPerUser dans l’appel. Sur les trois notifications envoyées, l’utilisateur de l’écouteur 1 reçoit des notifications de l’utilisateur 1 dans la session 0 ou la session 1. L’utilisateur de l’écouteur 2 reçoit des notifications de l’utilisateur 2 dans la session 2.
Si les clients d’écoute indiqués dans la figure précédente avaient appelé RegisterForPrintAsyncNotifications, mais que cette fois-ci, en passant l’énumérateur kAllUsers dans l’appel, tous les écouteurs de toutes les sessions auraient reçu les trois notifications. Notez que seuls les administrateurs sont autorisés à utiliser l’énumérateur kAllUsers dans les appels à cette fonction.
Administrateurs
Un administrateur est un utilisateur disposant de droits PRINTER_ACCESS_ADMINISTER pour l’objet d’impression spécifié. Un administrateur peut envoyer des notifications à tout le monde et recevoir des notifications de n’importe qui. Notez que le filtre de notification est toujours appliqué.
Dans la figure suivante, Joe envoie une notification sur un canal avec un kPerUser. Lorsque le canal est filtré sur la base de cet énumérateur, la notification doit être envoyée uniquement aux sessions qui appartiennent à l’utilisateur 1, à savoir la session 1. Toutefois, la notification est également envoyée à la session 2, car un administrateur y écoute et écoute les notifications de ce type. Notez que l’administrateur de la session 3 ne reçoit pas la notification, car les types de notification ne sont pas les mêmes.
Spécification du type de communication
En spécifiant un type de communication, le composant d’impression indique si une réponse est attendue du client de l’écouteur, ainsi que la façon dont le spouleur gère le cas lorsque des notifications sont renvoyées à partir de plusieurs clients.
typedef enum
{
kBidirectional = 1,
kUnidirectional,
} PrintAsyncNotifyConversationStyle
Il existe deux types de communication : unidirectionnel et bidirectionnel. Dans la communication unidirectionnelle, un client à l’écoute ne répond pas à une notification de spouleur. Dans ce cas, le client à l’écoute ne peut pas renvoyer de notifications, car il reçoit un pointeur d’interface IPrintAsyncNotifyChannelNULL. Dans la communication bidirectionnelle, le client envoie une réponse lorsqu’il reçoit une notification et effectue une boîte de dialogue avec le composant d’impression. Il s’agit du cas de notification de l’interface utilisateur.
La situation dans laquelle plusieurs sessions reçoivent une notification d’interface utilisateur mérite un commentaire. Dans ce cas, le spouleur ouvre un canal et avertit tous les écouteurs qui correspondent aux filtres, en leur envoyant la première notification. Lorsque le premier écouteur répond, le spouleur ferme les autres canaux et le dialogue continue avec le premier client.
Si un administrateur (par exemple) se connecte avant qu’un client d’écoute inscrit ne réponde, l’administrateur reçoit la même notification d’interface utilisateur que le client à l’écoute.
Lorsque le premier utilisateur (l’administrateur, par exemple) envoie la réponse, le spouleur marque les connexions avec les autres clients comme « fermées ». Lorsque l’autre client à l’écoute finit par répondre, il reçoit un message « canal fermé ».
Notification Types
Le type de notification est un GUID que le spouleur accepte et utilise pour filtrer les clients de l’écouteur. (Voir la définition de type PrintAsyncNotificationType dans le fichier d’en-tête Prnasnot.h.) Tout client du mécanisme de notification asynchrone du spouleur peut définir son propre type de notification. Même si le spouleur ignore la signification du type de notification envoyé, il filtre toujours les clients de l’écouteur en fonction du type de notification.
Un type de données de notification doit être associé à chaque notification. Ce type identifie le schéma des données de notification.
En plus du type de données de notification, il existe un type associé au canal, le type de canal de notification. Un expéditeur de notification et un client à l’écoute utilisent le type de canal de notification à des fins différentes.
Du côté de l’expéditeur du canal, lorsqu’un composant d’impression ouvre un canal, il peut spécifier le type de notifications qu’il a l’intention d’envoyer via ce canal. Toutes les notifications passant par ce canal doivent être du même type que le type de canal de notification.
L’expéditeur doit toujours associer un type à une notification afin que le spouleur « sache » comment l’envoyer aux clients d’écoute appropriés. Un client à l’écoute doit valider les données selon son propre schéma. Le type de notification identifie ce schéma.
Du côté de l’écouteur du canal, un client à l’écoute peut demander à recevoir un type de notification en spécifiant un certain type de données de notification lors de l’inscription.
Le spouleur définit un type de notification spécial utilisé pour annoncer aux clients à l’écoute que le service ou l’application est mort.
const GUID NOTIFICATION_RELEASE;
Le client à l’écoute ne peut recevoir ce type de message que lorsque sa méthode IPrintAsyncNotifyCallback::ChannelClosed est appelée.
Handle d’inscription de notification
Lorsqu’un client s’inscrit aux notifications, le spouleur côté serveur gère une table interne contenant des informations sur l’application, telles que son contexte de sécurité. Le handle d’inscription de notification est une structure opaque que le client reçoit.
Le client peut annuler l’inscription pour recevoir des notifications uniquement à l’aide de ce handle.