Middleware

GILT FÜR: SDK v4

Middleware ist lediglich eine Klasse zwischen dem Adapter und der Bot-Logik, die während der Initialisierung der Middlewaresammlung Ihres Adapters hinzugefügt wird. Das SDK ermöglicht Ihnen das Schreiben eigener Middleware sowie das Hinzufügen von Middleware, die von anderen Entwicklern erstellt wurde. Jede ein- oder ausgehende Aktivität für Ihren Bot durchläuft Ihre Middleware.

Der Adapter verarbeitet und leitet eingehende Aktivitäten in der Bot-Middleware-Pipeline an die Logik Ihres Bots und dann wieder heraus. Während jede Aktivität den Bot durchläuft, kann jede Middleware die Aktivität überprüfen und beeinflussen, sowohl bevor als auch nachdem die Bot-Logik ausgeführt wurde.

Bevor Sie zu Middleware springen, ist es wichtig, Bots allgemein und wie sie Aktivitäten verarbeiten.

Verwendungsmöglichkeiten für Middleware

Häufig kommt die Frage auf: "Wann sollte ich Aktionen als Middleware implementieren und meine normale Botlogik verwenden?" Middleware bietet Ihnen zusätzliche Möglichkeiten, mit dem Unterhaltungsfluss Ihrer Benutzer sowohl vor als auch nach jeder Drehung der Unterhaltung zu interagieren. Darüber hinaus können Sie mit Middleware auch Informationen zur Konversation speichern und abrufen und bei Bedarf weitere Verarbeitungslogik aufrufen. Unten sind einige häufige Szenarien angegeben, die zeigen, wann Middleware hilfreich sein kann.

Ansehen oder Beeinflussen jeder Aktivität

Es gibt viele Situationen, in denen Ihr Bot jede Aktivität bzw. jede Aktivität eines bestimmten Typs behandeln sollte. Sie können beispielsweise jede Nachrichtenaktivität protokollieren, die Ihr Bot empfängt oder eine Fallbackantwort bereitstellt, wenn der Bot eine Antwort nicht anderweitig generiert hat. Middleware ist ein großartiger Ort für solche Prozesse, mit seiner Fähigkeit, sowohl vor als auch nach der restlichen Botlogik zu handeln.

Ändern und Erweitern des Turn-Kontexts

Bestimmte Konversationen können erfolgreicher sein, wenn der Bot über mehr Informationen verfügt, als in der Aktivität bereitgestellt werden. In diesem Fall kann Middleware auf die bisher verfügbaren Informationen zum Konversationszustand zugreifen, eine externe Datenquelle abfragen und diese an das Turn-Kontextobjekt anfügen, bevor die Ausführung an die Bot-Logik übergeben wird.

Im SDK ist das Protokollieren der Middleware definiert, mit der ein- und ausgehende Aktivitäten aufgezeichnet werden können, aber Sie können auch Ihre eigene Middleware definieren.

Die Bot-Middlewarepipeline

Der Adapter ruft für jede Aktivität Middleware in der Reihenfolge auf, in der Sie sie hinzugefügt haben. Der Adapter übergibt das Kontextobjekt für den Turn und einen next-Delegaten, und die Middleware ruft den Delegaten auf, um die Steuerung an die nächste Middleware in der Pipeline zu übergeben. Middleware hat auch die Möglichkeit, Aktionen durchzuführen, nachdem der next-Delegat zurückgegeben wird, bevor die Methode abgeschlossen wird. Sie können es sich so vorstellen, dass jedes Middleware-Objekt die Möglichkeit hat, in Bezug auf Middleware-Objekte, die in der Pipeline folgen, als erstes und als letztes zu agieren.

Beispiel:

  • Der Turnhandler des ersten Middleware-Objekts führt Code vor dem nächsten Aufruf aus.
    • Der Turnhandler des zweiten Middleware-Objekts führt Code vor dem nächsten Aufruf aus.
      • Der Turnhandler des Bots wird ausgeführt und zurückgegeben.
    • Der Turnhandler des zweiten Middleware-Objekts führt vor der Rückgabe alle verbleibenden Code aus.
  • Der Turnhandler des ersten Middleware-Objekts führt vor der Rückgabe alle verbleibenden Code aus.

Wenn Middleware die nächste Stellvertretung nicht aufruft, ruft der Adapter keine der nachfolgenden Middleware- oder Bot-Turnhandler auf, und die Pipeline-Kurzschaltungen.

Nach Abschluss der Bot-Middlewarepipeline endet der Turn und der Gültigkeitsbereich des Turn-Kontexts.

Die Middleware oder der Bot kann Antworten generieren und Antwortereignishandler registrieren. Beachten Sie, dass Antworten in separaten Prozessen verarbeitet werden.

Reihenfolge der Middleware

Die Reihenfolge, in der die Middleware hinzugefügt wird, ist eine wichtige Entscheidung, da sie bestimmt, in welcher Reihenfolge die Middleware eine Aktivität verarbeitet.

Hinweis

Damit soll ein allgemeines Muster bereitgestellt werden, das für die meisten Bots funktioniert. Beachten Sie jedoch, wie jeder Teil der Middleware mit den Anderen in Ihrer Situation interagiert.

Middleware, die sich um die Aufgaben auf niedrigster Ebene kümmert, die jedem Bot hinzugefügt werden sollen, sollte zuerst ihrer Middlewarepipeline hinzugefügt werden. Hierzu gehören beispielsweise die Protokollierung, die Ausnahmebehandlung und die Übersetzung. Ordnen Sie diese je nach Ihren Anforderungen an, z. B. ob die eingehende Nachricht zuerst übersetzt werden soll, bevor Nachrichten gespeichert werden oder wenn der Nachrichtenspeicher zuerst erfolgen soll, was bedeutet, dass gespeicherte Nachrichten nicht übersetzt werden.

Botspezifische Middleware sollte ihrer Middlewarepipeline zuletzt hinzugefügt werden, Middleware, die Sie implementieren, um eine Verarbeitung für jede Nachricht auszuführen, die an Ihren Bot gesendet wird. Wenn Ihre Middleware Zustandsinformationen oder andere Informationen im Kontext des Bots verwendet, fügen Sie sie nach der Middleware, die den Zustand oder Kontext ändert, der Middleware-Pipeline hinzu.

Kurzschlüsse

Kurzschlüsse sind ein wichtiges Konzept bei der Middleware (und bei Antworthandlern). Wenn die Ausführung durch die nachfolgenden Ebenen fortgesetzt werden soll, ist eine Middleware (oder ein Antworthandler) erforderlich, um die Ausführung durch Aufrufen des next-Delegaten zu übergeben. Wenn die nächste Stellvertretung nicht innerhalb dieser Middleware (oder Reaktionshandler) aufgerufen wird, werden die zugeordneten Pipeline-Kurzschaltungen und nachfolgende Ebenen nicht ausgeführt. Dies bedeutet, dass die gesamte Botlogik sowie jegliche Middleware im weiteren Verlauf der Pipeline übersprungen wird. Es gibt einen subtilen Unterschied zwischen Ihrer Middleware und Dem Antworthandler, der eine Drehung abschließt.

Wenn Middleware-Kurzschaltungen eine Drehung durchführen, wird der Bot-Turnhandler nicht aufgerufen, aber alle Middleware-Code, der vor diesem Punkt in der Pipeline ausgeführt wird, wird weiterhin ausgeführt.

Bei Ereignishandlern bedeutet nicht der nächste Aufruf, dass das Ereignis abgebrochen wird, was sich von der Middleware-Übersprunglogik unterscheidet. Wenn der Rest des Ereignisses nicht verarbeitet wird, sendet der Adapter es nicht.

Tipp

Stellen Sie sicher, dass es dem gewünschten Verhalten entspricht, wenn Sie für ein Antwortereignis wie SendActivities einen Kurzschluss durchführen. Andernfalls kann es schwierig sein, Fehler zu beheben.

Antwortereignishandler

Zusätzlich zur Anwendungs- und Middlewarelogik können Antworthandler (manchmal auch als Ereignishandler oder Aktivitätsereignishandler bezeichnet) dem Kontextobjekt hinzugefügt werden. Diese Ereignishandler werden aufgerufen, wenn die dazugehörige Antwort im aktuellen Kontextobjekt vor der Ausführung der tatsächlichen Antwort stattfindet. Diese Handler sind nützlich, wenn Sie wissen, dass Sie vor oder nach dem eigentlichen Ereignis etwas für jede Aktivität dieses Typs für den Rest der aktuellen Antwort tun wollen.

Warnung

Achten Sie darauf, eine Aktivitätsantwortmethode nicht in ihrem jeweiligen Antwortereignishandler aufzurufen, z. B. indem Sie die SendActivity-Methode in einem onSendActivity-Handler aufrufen. Anderenfalls wird eine Endlosschleife generiert.

Beachten Sie, dass jede neue Aktivität einen neuen Thread für die Ausführung erhält. Wenn der Thread zur Verarbeitung der Aktivität erstellt wird, wird die Liste der Handler für diese Aktivität in den neuen Thread kopiert. Handler, die nach diesem Punkt hinzugefügt wurden, werden für dieses spezielle Aktivitätsereignis nicht ausgeführt. Die in einem Kontextobjekt registrierten Handler werden ähnlich behandelt, wie der Adapter die Middlewarepipeline verwaltet. Handler werden daher in der Reihenfolge aufgerufen, in der sie hinzugefügt wurden, und der Aufruf des nächsten Delegaten übergibt die Steuerung an den nächsten registrierten Ereignishandler. Wenn ein Handler die nächste Stellvertretung nicht aufruft, werden keine der nachfolgenden Ereignishandler aufgerufen, die Ereigniskürkel, und der Adapter sendet die Antwort nicht an den Kanal.

Verarbeiten des Zustands in Middleware

Eine gängige Methode zum Speichern des Zustands ist das Aufrufen der „save changes“-Methode am Ende des Turn-Handlers. Hier ist ein Diagramm mit dem Fokus auf den Anruf.

Sequenzdiagramm einer Bot-Drehung, wobei der Zustand, der vom Turnhandler des Bots gespeichert wird.

Das Problem mit diesem Ansatz besteht darin, dass alle Zustandsupdates, die aus einer benutzerdefinierten Middleware vorgenommen werden, die nach der Rückgabe des Bots an den dauerhaften Speicher erfolgt. Die Lösung besteht darin, den Aufruf der SaveChanges-Methode zu verschieben und nach dem Abschluss der benutzerdefinierten Middleware auszuführen. Dazu wird eine Instanz der auto-save changes-Middleware am Anfang des Middlewarestapels oder spätestens vor der Middleware, die den Zustand möglicherweise aktualisiert, hinzugefügt. Die Ausführung ist unten dargestellt.

Sequenzdiagramm einer Bot-Drehung, wobei der Zustand aus Middleware gespeichert ist.

Fügen Sie die Objekte für die Zustandsverwaltung hinzu, die eine Aktualisierung eines BotStateSet-Objekts erfordern, und verwenden Sie diese dann, wenn Sie Ihre „auto-save changes“-Middleware erstellen.

Zusätzliche Ressourcen

Sie können sich die Middleware für die Transkriptprotokollierung ansehen, die im Bot Framework SDK implementiert ist [C# | JS].