发布C#Bot一段时间后会遇到内部服务器错误

时间:2018-03-16 13:31:53

标签: c# azure botframework

大家好日子,

我正在为我的公司创建一个聊天机器人,我开始使用github上的示例和框架文档。

我们决定在Azure上托管它,并为其添加了LUIS和表存储。 Bot在Botframework Emulator中本地运行良好,但在Azure(WebChat,Telegram)上,如果没有人试图与机器人通信,它将只运行大约一小时到一小时十五分钟。在这段时间之后,机器人将遇到内部服务器错误。当你问机器人的东西时,你可以延长这个时间窗口(我不知道多长时间以及为什么我也不知道,对不起)。

在Azure" 始终开启"设置为true。

我现在非常沮丧,因为我找不到问题,而且我很确定我的代码一定有问题,因为我不能正确理解框架。我还是Azure,C#和Bot Framework的初学者。 此外,我已经阅读了所有关于"内部服务器错误""在这里和github。也尝试调试,即使VS中有额外的Debbug选项。我们已经尝试了Application Insights。

目前,我正在使用LUIS Dialog执行所有操作/调用/转发给其他IDialogs:

    [LuisIntent(Intent_Existens)]
    public async Task ExistensOf(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
    {
        var existens = new ExistensDialog();
        var messageToForward = await message;

        if (result.Entities.Count == 1)
        {
            messageToForward.Value = result.Entities[0].Entity;
            await context.Forward(existens, AfterDialog, messageToForward);
        }
        else
        {
            context.Wait(this.MessageReceived);
        }
    }

我知道&#34;价值&#34;适用于CardActions,但我不知道如何将实体传递给子对话框。

    [Serializable]
    public class ExistensDialog : IDialog<object>
    {
        public async Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            var message = await result;

            if (message.Text.Contains("specificWord"))
            {
                await context.Forward(new ExistensHU(), AfterDialog, message);
            }
            else
            {
                await context.Forward(new ExistensBin(), AfterDialog, message);
            }
        }

        private async Task AfterDialog(IDialogContext context, IAwaitable<object> result)
        {
            context.Done<object>(null);
        }
    }

然后:

    [Serializable]
    internal class ExistensHU : IDialog<object>
    {
        private Renamer renamer = new Renamer(); // Just for renaming
        private ExternalConnection ec = new ExternalConnection(); //Just a HTTP connection to a WebApp to get data from it

        public async Task StartAsync(IDialogContext context)
        {
            context.Wait(MessageReceivedAsync);
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            const string apiCallURL = "some/API/"; // ExternalConnection...

            var message = await result;

            string nameHU = renamer.RemoveBlanks(message.Value.ToString());

            StringBuilder answerBuilder = new StringBuilder();

            var name = ec.CreateSingleAPIParameter("name", nameHU);
            Dictionary<string, string> wms = await ec.APIResultAsDictionary(apiCallURL, name);

            foreach (var item in wms)
            {
                if (item.Key.Equals("none") && item.Value.Equals("none"))
                {
                    answerBuilder.AppendLine($"Wrong Answer"); 
                }
                else
                {
                    answerBuilder.AppendLine($"Correct Answer");
                }
            }
            await context.PostAsync(answerBuilder.ToString());
            context.Done<object>(null);
        }
    }

这基本上是我项目中的每个Dialog。 我也有一个看起来像这样的IDialog:

    [Serializable]
    public class VerificationDialog : IDialog<object>
    {
        [NonSerializedAttribute]
        private readonly LuisResult _luisResult;

        public VerificationDialog(LuisResult luisResult)
        {
            _luisResult = luisResult;
        }

        public async Task StartAsync(IDialogContext context)
        {
            var message = _luisResult.Query;

            if (!message.StartsWith("Wie viele"))
            {
               context.Call(new ByVerificationDialog(_luisResult), AfterDialog);
            }
            else
            {
               context.Call(new CountBinsByVerification(_luisResult), AfterDialog);
            }
        }

        private async Task AfterDialog(IDialogContext context, IAwaitable<object> result)
        {
            context.Done<object>(null);
        }
    }

我不知道我是否允许从BasicLuisDialog传递这样的luisResult。这可能是问题或其中一个问题。

基本上,我和它仍然习惯了这个框架。我不期待绝对的答案。只是提示/提示和建议如何让一切变得更好。

提前致谢!

2 个答案:

答案 0 :(得分:3)

如果您使用的是.NET SDK 3.14.0.7版。目前我们正在跟踪此版本中的错误。有很多报道,我们正在积极调查。请尝试降级到3.13.1。在我们发布新版本之前,这应该为您解决问题。

供参考,我们正在跟踪这些GitHub问题: https://github.com/Microsoft/BotBuilder/issues/4322 https://github.com/Microsoft/BotBuilder/issues/4321

2014年3月21日更新:

我们推出了新版本的SDK,其中包含针对此问题https://www.nuget.org/packages/Microsoft.Bot.Builder/3.14.1.1

的修复程序

答案 1 :(得分:1)

内部错误通常表示.NET应用程序中的异常。

使用deep接收所有未处理的异常并将其记录在某处(考虑使用Application Insights)。 在您调查记录的信息后,修复该问题。