跳转到主要内容

热门内容

今日:


总体:


最近浏览:


Chinese, Simplified

category

中间件只是位于适配器和bot逻辑之间的一个类,在初始化期间添加到适配器的中间件集合中。SDK允许您编写自己的中间件或添加他人创建的中间件。进入或退出机器人的每一个活动都会通过中间件进行。

适配器处理传入的活动,并通过机器人程序中间件管道将其引导到机器人程序的逻辑,然后再次退出。当每个活动进出机器人程序时,每个中间件都可以在机器人程序逻辑运行之前和之后检查活动或对其采取行动。

在进入中间件之前,了解机器人的一般情况以及它们如何处理活动是很重要的。

中间件的用途


这个问题经常出现:“与使用我的正常机器人逻辑相比,我什么时候应该作为中间件实现操作?”中间件为您提供了额外的机会,可以在每次会话处理之前和之后与用户的会话流进行交互。中间件还允许您存储和检索有关会话的信息,并在需要时调用额外的处理逻辑。以下是一些常见的场景,展示了中间件的有用之处。

观察或执行每一项活动


有很多情况需要你的机器人对每一项活动或某一类型的每一项行动都做一些事情。例如,您可能希望记录您的机器人接收到的每一条消息活动,或者如果机器人本次没有生成响应,则提供后备响应。中间件是处理此类进程的好地方,它能够在机器人程序逻辑的其余部分执行之前和之后进行操作。

修改或增强转弯上下文


如果机器人拥有比活动中提供的信息更多的信息,那么某些对话可能会更有成效。在这种情况下,中间件可以查看到目前为止的会话状态信息,查询外部数据源,并在将执行传递给bot逻辑之前将其附加到turn上下文对象。

SDK定义了可以记录传入和传出活动的日志中间件,但您也可以定义自己的中间件。

bot中间件管道


对于每个活动,适配器都会按照您添加的顺序调用中间件。适配器会传入回合的上下文对象和下一个委托,中间件会调用委托将控制权传递给管道中的下一个中间件。中间件也有机会在下一个委托返回后完成该方法。您可以将其视为每个中间件对象都有第一次也是最后一次机会对管道中跟随它的中间件对象采取行动。

例如

  • 第一个中间件对象的回合处理程序在调用下一个之前执行代码。
    • 第二个中间件对象的回合处理程序在调用下一个之前执行代码。
      • 机器人的回合处理程序执行并返回。
    • 第二个中间件对象的回合处理程序在返回之前执行任何剩余的代码。
  • 第一个中间件对象的turn处理程序在返回之前执行任何剩余的代码。


如果中间件没有调用下一个委托,那么适配器就不会调用任何后续的中间件或bot回合处理程序,并且管道会短路。

一旦bot中间件管道完成,转换就结束了,并且转换上下文超出了范围。

中间件或机器人程序可以生成响应并注册响应事件处理程序,但请记住,响应是在单独的过程中处理的。

中间件顺序


由于中间件的添加顺序决定了中间件处理活动的顺序,因此决定添加中间件的顺序非常重要。

笔记

这是为了给您提供一个适用于大多数机器人的通用模式,但一定要考虑到每一个中间件将如何根据您的情况与其他中间件交互。

负责处理每个机器人程序的最低级别任务的中间件应该首先添加到中间件管道中。示例包括日志记录、异常处理和翻译。根据您的需要订购这些邮件,例如您是否希望在存储邮件之前先翻译传入邮件,或者是否应先进行邮件存储,这可能意味着存储的邮件不会被翻译。

最后,应该将特定于机器人的中间件添加到您的中间件管道中,这是您实现的中间件,用于对发送到机器人的每条消息进行一些处理。如果您的中间件使用了机器人上下文中设置的状态信息或其他信息,请在修改状态或上下文的中间件之后将其添加到中间件管道中。

短路


关于中间件和响应处理程序的一个重要思想是短路。如果要继续执行,则需要中间件(或响应处理程序)通过调用其下一个委托来传递执行。如果没有在该中间件(或响应处理程序)中调用下一个委托,则不会执行相关的管道短路和后续层。这意味着所有机器人程序逻辑以及管道中的任何中间件都将被跳过。您的中间件和缩短转弯的响应处理程序之间有一个细微的区别。

当中间件使回合短路时,将不会调用您的bot回合处理程序,但在此之前在管道中执行的所有中间件代码仍将运行到完成。

对于事件处理程序来说,不调用next意味着事件被取消,这与中间件跳过逻辑非常不同。由于不处理事件的其余部分,适配器永远不会发送它。

提示

如果您确实短路了响应事件,例如SendActivities,请确保它是您想要的行为。否则,可能会导致难以修复错误。

响应事件处理程序


除了应用程序和中间件逻辑之外,还可以向上下文对象添加响应处理程序(有时也称为事件处理程序或活动事件处理程序)。当关联的响应发生在当前上下文对象上时,在执行实际响应之前,会调用这些处理程序。当您知道要在实际事件之前或之后对当前响应的其余部分执行该类型的每个活动时,这些处理程序非常有用。

警告

请注意不要从相应的响应事件处理程序中调用活动响应方法,例如,从发送时的活动处理程序内调用发送活动方法。这样做可以生成一个无限循环。

请记住,每个新活动都会有一个新的线程来执行。当创建了处理该活动的线程时,该活动的处理程序列表会复制到该新线程。在该点之后添加的任何处理程序都不会针对该特定活动事件执行。在上下文对象上注册的处理程序的处理方式与适配器管理中间件管道的方式类似。也就是说,处理程序按照添加的顺序被调用,调用下一个委托将控制权传递给下一个注册的事件处理程序。如果处理程序没有调用下一个委托,则不会调用任何后续事件处理程序,事件短路,适配器也不会向通道发送响应。

中间件中的处理状态


保存状态的常用方法是在转弯处理程序结束时调用save changes方法。这是一张重点关注通话的图表。

机器人转弯的序列图,状态从机器人的转弯处理程序中保存。

这种方法的问题是,在机器人程序的回合处理程序返回后,由某些自定义中间件进行的任何状态更新都不会保存到持久存储中。解决方案是通过将自动保存更改中间件的实例添加到中间件堆栈的开头,或者至少在任何可能更新状态的中间件之前,将对保存更改方法的调用移动到自定义中间件完成之后。执行情况如下所示。

机器人程序转弯的序列图,状态从中间件中保存。

将需要更新的状态管理对象添加到bot状态集对象中,然后在创建自动保存更改中间件时使用该对象。

额外资源

  • You can take a look at the transcript logger middleware, as implemented in the Bot Framework SDK [C# | JS].
本文地址
最后修改
星期一, 七月 1, 2024 - 22:06
Article