Partilhar via


Middleware

APLICA-SE A: SDK v4

O middleware é simplesmente uma classe situada entre o adaptador e a lógica do bot, adicionada à coleção de middleware do adaptador durante a inicialização. O SDK permite-lhe escrever o seu próprio middleware ou adicionar middleware criado por outros. Todas as atividades que entram ou saem do bot passam pelo middleware.

O adaptador processa e direciona as atividades de entrada através do pipeline de middleware bot para a lógica do seu bot e, em seguida, recua novamente. À medida que cada atividade entra e sai do bot, cada peça de middleware pode inspecionar ou agir sobre a atividade, tanto antes como depois da lógica do bot ser executada.

Antes de saltar para o middleware, é importante entender os bots em geral e como eles processam atividades.

Utilizações para middleware

A questão surge frequentemente: "Quando devo implementar ações como middleware versus usando a minha lógica bot normal?" O Middleware oferece-lhe oportunidades extra para interagir com o fluxo de conversação dos seus utilizadores antes e depois de cada viragem da conversação ser processada. O Middleware também permite armazenar e recuperar informações sobre a conversação e chamar a lógica de processamento adicional quando necessário. Abaixo estão alguns cenários comuns que mostram onde o middleware pode ser útil.

Olhar ou agir em todas as atividades

Há muitas situações que exigem que o seu bot faça algo em cada atividade, ou para cada atividade de um certo tipo. Por exemplo, pode querer registar todas as atividades de mensagens que o seu bot recebe ou fornecer uma resposta de retorno se o bot não tiver gerado uma resposta desta vez. Middleware é um ótimo lugar para tais processos, com a sua capacidade de agir antes e depois que o resto da lógica bot foi executado.

Modificar ou melhorar o contexto de viragem

Certas conversas podem ser muito mais frutíferas se o bot tiver mais informação do que o que é fornecido na atividade. O middleware neste caso poderia olhar para a informação do estado de conversação que tem até agora, consultar uma fonte de dados externa, e anexar isso ao objeto de contexto de turn antes de passar a execução para a lógica bot.

O SDK define o middleware de registo que pode gravar atividades de entrada e saída, mas também pode definir o seu próprio middleware.

O gasoduto bot middleware

Para cada atividade, o adaptador chama middleware na ordem em que o adicionou. O adaptador passa no objeto de contexto para a curva e um próximo delegado, e o middleware chama o delegado para passar o controlo para o próximo middleware no pipeline. Middleware também tem a oportunidade de fazer as coisas após o próximo delegado retornar antes de completar o método. Pode pensar nisso como cada objeto de middleware tem a primeira e última oportunidade de agir em relação aos objetos de middleware que o seguem no oleoduto.

Por exemplo:

  • O primeiro manipulador de turno do objeto de middleware executa o código antes de ligar a seguir.
    • O manipulador de turno do segundo objeto de middleware executa o código antes de ligar a seguir.
      • O manipulador de turno do bot executa e regressa.
    • O manipulador de turno do segundo objeto de middleware executa qualquer código restante antes de voltar.
  • O manipulador de turno do primeiro objeto de middleware executa qualquer código restante antes de voltar.

Se o middleware não ligar para o próximo delegado, o adaptador não chama nenhum dos seguintes manipuladores de ligação de middleware ou bot, e o pipeline curto-circuitos.

Uma vez concluído o gasoduto bot middleware, a curva acaba e o contexto de viragem fica fora de alcance.

O middleware ou o bot podem gerar respostas e registar manipuladores de eventos de resposta, mas tenha em mente que as respostas são tratadas em processos separados.

Ordem de middleware

Uma vez que a ordem em que o middleware é adicionado determina a ordem em que o middleware processa uma atividade, é importante decidir a sequência de que o middleware deve ser adicionado.

Nota

Isto é para lhe dar um padrão comum que funciona para a maioria dos bots, mas não se esqueça de considerar como cada peça de middleware irá interagir com os outros para a sua situação.

Middleware que cuida das tarefas de nível mais baixo que a cada bot deve ser adicionado primeiro ao seu pipeline de middleware. Exemplos incluem registo, tratamento de exceções e tradução. Encomende estes dependendo das suas necessidades, tais como se pretende que a mensagem recebida seja traduzida primeiro, antes de as mensagens serem armazenadas, ou se o armazenamento de mensagens deve ocorrer primeiro, o que pode significar que as mensagens armazenadas não serão traduzidas.

O meio-fio de médio específico do bot deve ser adicionado ao seu pipeline de middleware por último, o middleware que implementa para fazer algum processamento em cada mensagem enviada para o seu bot. Se o seu middleware utilizar informações estatais ou outras informações definidas no contexto bot, adicione-a ao gasoduto middleware após o middleware que modifica o estado ou o contexto.

Curto-circuito

Uma ideia importante em torno do middleware e dos manipuladores de resposta é o curto-circuito. Se a execução continuar através das camadas que o seguem, o middleware (ou um manipulador de resposta) é obrigado a passar a execução chamando o seu próximo delegado. Se o próximo delegado não for chamado dentro desse middleware (ou manipulador de resposta), os curto-circuitos de gasoduto associado e as camadas subsequentes não são executados. Isto significa que toda a lógica bot, e qualquer middleware mais ao longo do oleoduto, é ignorado. Há uma diferença subtil entre o seu middleware e o seu manipulador de resposta a fazer um curto-circuito.

Quando o middleware circuitos de uma curva, o seu bot turn handler não será chamado, mas todo o código de middleware executado antes deste ponto no oleoduto ainda estará concluído.

Para os manipuladores de eventos, não ligar a seguir significa que o evento é cancelado, o que é muito diferente da lógica de salto de middleware. Ao não processar o resto do evento, o adaptador nunca o envia.

Dica

Se fizer um curto-circuito num evento de resposta, por SendActivitiesexemplo, certifique-se de que é o comportamento que pretende. Caso contrário, pode resultar em difícil correção de erros.

Manipuladores de eventos de resposta

Além da lógica de aplicação e middleware, os manipuladores de resposta (também por vezes referidos como manipuladores de eventos, ou manipuladores de eventos de atividade) podem ser adicionados ao objeto de contexto. Estes manipuladores são chamados quando a resposta associada acontece no objeto de contexto atual, antes de executar a resposta real. Estes manipuladores são úteis quando você sabe que você vai querer fazer algo, antes ou depois do evento real, para cada atividade desse tipo para o resto da resposta atual.

Aviso

Tenha cuidado para não chamar um método de resposta de atividade dentro do respetivo manipulador de eventos de resposta, por exemplo, chamando o método de atividade de envio de dentro de um manipulador de atividade de envio. Fazê-lo pode gerar um loop infinito.

Lembre-se, cada nova atividade recebe um novo fio para executar. Quando o fio para processar a atividade é criado, a lista de manipuladores para essa atividade é copiada para esse novo fio. Nenhum manipulador adicionado após esse ponto será executado para esse evento de atividade específica. Os manipuladores registados num objeto de contexto são manuseados da mesma forma que o adaptador gere o gasoduto middleware. Ou seja, os manipuladores são chamados na ordem que são adicionados, e chamar o próximo delegado passa o controlo para o próximo manipulador de eventos registado. Se um manipulador não ligar para o próximo delegado, nenhum dos seguintes manipuladores de eventos é chamado, o evento curto-circuitos, e o adaptador não envia a resposta para o canal.

Estado de manuseamento em middleware

Um método comum para salvar o estado é chamar o método de poupança de alterações no final do manipulador de turno. Aqui está um diagrama com foco na chamada.

Diagrama de sequência de uma curva bot, com estado salvo do manipulador de turno do bot.

O problema com esta abordagem é que quaisquer atualizações estatais feitas a partir de algum middleware personalizado que acontece após o retorno do bot de volta não serão guardadas para armazenamento durável. A solução é mover a chamada para o método de poupança de alterações para depois de o middleware personalizado ter concluído, adicionando uma instância do middleware de poupança automática para o início da stack de middleware, ou pelo menos antes de qualquer um dos middleware que possam atualizar o estado. A execução é mostrada abaixo.

Diagrama de sequência de uma curva bot, com estado guardado de middleware.

Adicione os objetos de gestão do estado que precisarão de ser atualizados para um objeto de conjunto de estado de bot e, em seguida, use-os quando criar o seu middleware de poupança automática.

Recursos adicionais

Você pode dar uma olhada no middleware de trans transcrição, como implementado no Bot Framework SDK [C# | JS].