Tengo un problema en el que varios usuarios que acceden simultáneamente al mismo cuadro de diálogo tienen sus valores de aviso mezclados. El cuadro de diálogo en cuestión es un cuadro de diálogo Estado del pedido donde, entre otras cosas, se solicita el número de pedido. Veo casos en los que el usuario 1 consulta el pedido A, el usuario 2 consulta el pedido B (casi al mismo tiempo) y luego ambos usuarios reciben información para el pedido B.
Este es un cuadro de diálogo complejo y compartir el código completo no sería útil, pero aquí hay algunos puntos que creo que pueden ser relevantes:
this.queryData = {} en el constructor para iniciar un objeto que contenga todos los parámetros de consulta de pedido que estoy solicitando, incluido el número de pedido. return await step.prompt(TEXT_PROMPT, { prompt: `Please provide your ${step.values.orderTypeText} number.`, retryPrompt: `Please enter a valid ${step.values.orderTypeText} number.`, });this.queryData.orderNumber = step.result.trim().split(" ").splice(-1)[0];Y eso es todo, a menos que haya alguna forma de que no sea el valor de solicitud sino el mensaje completo lo que se envía al usuario equivocado (pero eso parece bastante improbable, además, en este ejemplo, va a ambos usuarios).
He considerado en lugar de usar this.queryData para almacenar la información en conversationState , pero no quiero rehacer el código a menos que pueda confirmar que este es un problema con la implementación que he usado, específicamente this.queryData en lugar de algún otro problema .
Como referencia, aquí está la definición de clase, hasta el final del constructor:
class viewOrderDialog extends ComponentDialog { constructor(dialogId, userDialogStateAccessor, userState, appInsightsClient, dialogState, conversationState) { super(dialogId); this.addDialog(new ChoicePrompt(CRITERIA_PROMPT)); this.addDialog(new TextPrompt(TEXT_PROMPT)); this.addDialog(new TextPrompt(LINE_PROMPT, this.validateLineNumber)); this.addDialog(new TextPrompt(EMAIL_PROMPT,this.validateEmail)); this.addDialog(new TextPrompt(ZIP_PROMPT,this.validateZip)); this.addDialog(new ConfirmPrompt(CONFIRM_PROMPT)); this.addDialog(new ChoicePrompt(CHOICE_PROMPT)); this.addDialog(new WaterfallDialog(WATERFALL_DIALOG, [ this.requestOrderNumber.bind(this), this.selectOrderType.bind(this), // This is being bypassed by current Filtration store implementation this.selectSearchCriteria.bind(this), this.getQueryData.bind(this), this.confirmBillingZip.bind(this), this.confirmBillingEmail.bind(this), this.displayLineStatus.bind(this), this.getEmailAddress.bind(this), this.setFollowUp.bind(this), this.loopStep.bind(this) ])); this.initialDialogId = WATERFALL_DIALOG; this.queryData = {}; // State accessors this.userDialogStateAccessor = userDialogStateAccessor; this.userState = userState; this.dialogState = dialogState; this.conversationState = conversationState; this.appInsightsClient = appInsightsClient; this.addDialog(new PaginateDialog(PAGINATE_DIALOG, this.userDialogStateAccessor, userState, this.appInsightsClient)); // Luis Recognizer this.luisRecognizer = new LuisRecognizer({ applicationId: process.env.LuisAppId, endpointKey: process.env.LuisAPIKey, endpoint: `https://${ process.env.LuisAPIHostName }` }, { includeAllIntents: true, includeInstanceData: true, spellCheck: true, bingSpellCheckSubscriptionKey: process.env.bingAPIKey }, true); } // End constructorEstoy acostumbrado a trabajar con Botframework con .net, pero creo que el mecanismo general no diferirá demasiado del nodo.
En la implementación .net de BotBuilder, como dijiste, todas las instancias de los diálogos se almacenan en una sola instancia en el inicio de la aplicación para evitar una carga de instancias de diálogo que se ejecutan con casi los mismos datos.
Para evitar mezclar información entre instancias de diálogos, tiene algunas opciones:
stepContext.options y será recuperable en cualquier paso mientras el diálogo permanece en la pila (antes de llegar al paso final, llame a endDialog o replaceDialog ). Aquí alguna información sobre cómo almacenar datos:
https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-storage?view=azure-bot-service-4.0&tabs=javascript
@Arie Rodrigues me hizo ir en la dirección correcta, pero la solución no fue del todo correcta. De hecho, Bot Framework parece estar usando una sola instancia del diálogo, controlado por el estado de conversación/diálogo. Entonces, el objeto this.queryData definido en el constructor en realidad estaba siendo compartido por todos los diálogos. Con el momento adecuado, las entradas de solicitud se cruzaban del cuadro de diálogo de un usuario al otro.
Esto podría resolverse con cualquier método para guardar estos valores de forma no global. El estado de la conversación sería bueno, pero no necesitaba ni quería guardar los valores durante la conversación ni perder el tiempo recuperando y guardando el estado en cada paso. En cambio, usé step.values en lugar de this.queryData . Mi código en realidad se había basado en algunos valores de this.queryData que persistían cuando el cuadro de diálogo se repetía en cierto paso a través replaceDialog() , por lo que tenía que asegurarme de pasarlos en las opciones de ese método. Esto parece haber solucionado el problema, ya que tuve 4 probadores que accedieron a los mismos cuadros de diálogo al mismo tiempo con diferentes valores de solicitud sin problemas.