Benachrichtigungsfilterung und Kommunikationsstile
In diesem Abschnitt wird die Schnittstelle zwischen dem Spoolerprozess und Druckkomponenten wie Druckprozessor, Treiber und Monitor beschrieben.
Benachrichtigungsfilterung
Der aufgezählte PrintAsyncNotifyUserFilter-Typ wird für zwei Situationen verwendet. Im ersten davon ruft eine Druckkomponente, die im Spooler ausgeführt wird, die CreatePrintAsyncNotifyChannel-Funktion auf, um einen Benachrichtigungskanal zu erstellen. Der Aufrufer übergibt einen Enumerator des Aufzählungstyps PrintAsyncNotifyUserFilter, um anzugeben, welche lauschenden Clients Benachrichtigungen empfangen dürfen. In der zweiten Situation ruft ein lauschende Client die RegisterForPrintAsyncNotifications-Funktion auf, um sich für Benachrichtigungen zu registrieren. Der Aufrufer übergibt einen der PrintAsyncNotifyUserFilter-Enumeratoren, um anzugeben, welche Benachrichtigungen er empfangen soll.
typedef enum
{
kPerUser,
kAllUsers
} PrintAsyncNotifyUserFilter;
In der folgenden Abbildung wird der kPerUser-Enumerator im Aufruf der CreatePrintAsyncNotifyChannel-Funktion verwendet. Daher dürfen nur die Listener, die im selben Benutzerkonto wie der Benutzer ausgeführt werden, der die Registrierung vorgenommen hat, Benachrichtigungen empfangen.
In der nächsten Abbildung wird der kAllUsers-Enumerator im Aufruf der CreatePrintAsyncNotifyChannel-Funktion verwendet. Dadurch können alle Listener, die sich für den Drucker oder Server interessieren, Benachrichtigungen erhalten. Beachten Sie, dass nur Administratoren die Einstellung kAllUsers in Aufrufen dieser Funktion verwenden dürfen.
Die nächste Abbildung zeigt die Situation, in der sowohl Benutzer 1 als auch Benutzer 2 sich für Benachrichtigungen registriert haben, indem die Funktion RegisterForPrintAsyncNotifications aufgerufen und der kPerUser-Enumerator im Aufruf übergeben wird. Von den drei gesendeten Benachrichtigungen empfängt Listener User 1 Benachrichtigungen von Benutzer 1 in Sitzung 0 oder Sitzung 1. Listener Benutzer 2 empfängt Benachrichtigungen von Benutzer 2 in Sitzung 2.
Wenn die in der vorherigen Abbildung gezeigten Überwachungsclients RegisterForPrintAsyncNotifications aufgerufen hätten, diesmal aber den kAllUsers-Enumerator im Aufruf übergeben hätten, hätten alle Listener in allen Sitzungen die drei Benachrichtigungen erhalten. Beachten Sie, dass nur Administratoren den kAllUsers-Enumerator in Aufrufen dieser Funktion verwenden dürfen.
Administrators
Ein Administrator ist ein Benutzer mit PRINTER_ACCESS_ADMINISTER Rechten für das angegebene Druckobjekt. Ein Administrator kann Benachrichtigungen an jeden senden und Benachrichtigungen von jedem empfangen. Beachten Sie, dass der Benachrichtigungsfilter weiterhin erzwungen wird.
In der folgenden Abbildung sendet Joe eine Benachrichtigung auf einem Kanal mit einem kPerUser. Wenn der Kanal anhand dieses Enumerators gefiltert wird, sollte die Benachrichtigung nur an Sitzungen gesendet werden, die zu Benutzer 1 gehören, nämlich an Sitzung 1. Die Benachrichtigung wird jedoch auch an Sitzung 2 gesendet, da dort ein Administrator lauscht und auf Benachrichtigungen dieses Typs lauscht. Beachten Sie, dass der Administrator in Sitzung 3 die Benachrichtigung nicht empfängt, da die Benachrichtigungstypen nicht identisch sind.
Angeben des Kommunikationstyps
Durch Angabe eines Kommunikationstyps gibt die Druckkomponente an, ob eine Antwort vom Listenerclient erwartet wird, sowie die Art und Weise, wie der Spooler den Fall behandelt, wenn Benachrichtigungen von mehreren Clients zurückgesendet werden.
typedef enum
{
kBidirectional = 1,
kUnidirectional,
} PrintAsyncNotifyConversationStyle
Es gibt zwei Arten der Kommunikation : unidirektional und bidirektional. In der unidirektionalen Kommunikation reagiert ein lauschende Client nicht auf eine Spoolerbenachrichtigung. In diesem Fall kann der abhörende Client keine Benachrichtigungen zurück senden, da er einen NULL-IPrintAsyncNotifyChannel-Schnittstellenzeiger empfängt. Bei bidirektionaler Kommunikation sendet der Client eine Antwort, wenn er eine Benachrichtigung empfängt, und führt einen Dialog mit der Druckkomponente. Dies ist der Benutzeroberflächenbenachrichtigungsfall.
Die Situation, in der mehrere Sitzungen eine Ui-Benachrichtigung erhalten, verdient einen Kommentar. In dieser Situation öffnet der Spooler einen Kanal und benachrichtigt alle Listener, die mit den Filtern übereinstimmen, und sendet ihnen die erste Benachrichtigung. Wenn der erste Listener antwortet, schließt der Spooler die anderen Kanäle, und der Dialog wird mit dem ersten Client fortgesetzt.
Wenn sich ein Administrator (z. B.) anmeldet, bevor ein registrierter Lauschclient antwortet, erhält der Administrator dieselbe Ui-Benachrichtigung wie der lauschend client.
Wenn der erste Benutzer (z. B. der Administrator) die Antwort sendet, markiert der Spooler die Verbindungen mit den anderen Clients als "geschlossen". Wenn der andere Abhörclient schließlich antwortet, erhält er eine "Kanal geschlossen"-Nachricht.
Benachrichtigungstypen
Der Benachrichtigungstyp ist eine GUID, die der Spooler akzeptiert und zum Filtern der Listenerclients verwendet. (Siehe die PrintAsyncNotificationType-Typdefinition in der Headerdatei Prnasnot.h.) Jeder Client des asynchronen Benachrichtigungsmechanismus für Spooler kann einen eigenen Benachrichtigungstyp definieren. Obwohl der Spooler die Bedeutung des gesendeten Benachrichtigungstyps nicht kennt, filtert er dennoch die Listenerclients basierend auf dem Benachrichtigungstyp.
Jeder Benachrichtigung muss ein Benachrichtigungsdatentyp zugeordnet sein. Dieser Typ identifiziert das Benachrichtigungsdatenschema.
Zusätzlich zum Benachrichtigungsdatentyp ist dem Kanal ein Typ zugeordnet, der Benachrichtigungskanaltyp. Ein Benachrichtigungssender und ein lauschender Client verwenden den Typ des Benachrichtigungskanals für unterschiedliche Zwecke.
Wenn eine Druckkomponente auf der Senderseite einen Kanal öffnet, kann sie den Typ der Benachrichtigungen angeben, die über diesen Kanal gesendet werden sollen. Alle Benachrichtigungen, die diesen Kanal durchlaufen, müssen vom gleichen Typ wie der Benachrichtigungskanaltyp sein.
Der Absender muss immer einen Typ einer Benachrichtigung zuordnen, damit der Spooler "weiß", wie er an die entsprechenden Lauschclients gesendet werden soll. Ein abhörnder Client muss die Daten nach seinem eigenen Schema überprüfen. Der Benachrichtigungstyp identifiziert dieses Schema.
Auf der Listenerseite des Kanals kann ein abhörnder Client einen Benachrichtigungstyp anfordern, indem er bei der Registrierung einen bestimmten Benachrichtigungsdatentyp angibt.
Der Spooler definiert einen speziellen Benachrichtigungstyp, der verwendet wird, um lauschenden Clients mitzuteilen, dass der Dienst oder die Anwendung gestorben ist.
const GUID NOTIFICATION_RELEASE;
Der abhörbare Client kann diese Art von Nachricht nur empfangen, wenn seine IPrintAsyncNotifyCallback::ChannelClosed-Methode aufgerufen wird.
Benachrichtigungsregistrierungshandle
Wenn sich ein Client für Benachrichtigungen registriert, verwaltet der serverseitige Spooler eine interne Tabelle mit Informationen zur Anwendung, z. B. den Sicherheitskontext. Das Benachrichtigungsregistrierungshandle ist eine undurchsichtige Struktur, die der Client empfängt.
Der Client kann die Registrierung für den Empfang von Benachrichtigungen nur mithilfe dieses Handle aufheben.