プロキシ環境下でBot Framework から QnA Makerを呼び出せない問題への対処
TL;DR
- Bot Frameworkを利用しAzure Bot Serviceし、QnA Maker を使用した開発を行った場合、プロキシ環境下では、QnA Makerのサービスに接続できない問題への対処方法
環境
- Visual Studio 2019 16.4.3
- .NET Core 2.1
- Microsoft.Bot.Builder.AI.QnA 4.7.1
- Microsoft.Bot.Builder.Integration.AspNet.Core 4.7.1
事象
- Visual Studio 2019 16.4.3
- .NET Core 2.1
- Microsoft.Bot.Builder.AI.QnA 4.7.1
- Microsoft.Bot.Builder.Integration.AspNet.Core 4.7.1
事象
Visual StudioでBot Serviceを起動し、Bot Framework EmulatorでQnA Makerを利用したBotをテストした場合、以下のようなメッセージが表示されサービスに接続できない
コード
private async Task AccessQnAMaker(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var results = await EchoBotQnA.GetAnswersAsync(turnContext);
if (results.Any())
{
await turnContext.SendActivityAsync(MessageFactory.Text("QnA Maker Returned: " + results.First().Answer), cancellationToken);
}
else
{
await turnContext.SendActivityAsync(MessageFactory.Text("Sorry, could not find an answer in the Q and A system."), cancellationToken);
}
}
エラー
var results = await EchoBotQnA.GetAnswersAsync(turnContext);
の行で以下のエラーが発生する
Bot Framework Emulator
The bot encounted an error or bug.
To continue to run this bot, please fix the bot source code.
AdapterWithErrorHandler.csでの例外(Exception)
at System.Net.Http.ConnectHelper.<ConnectAsync>d__2.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.<CreateConnectionAsync>d__44.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.<WaitForCreatedConnectionAsync>d__49.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.<SendWithRetryAsync>d__39.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.QnA.HttpRequestUtils.<ExecuteHttpRequestAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.QnA.GenerateAnswerUtils.<QueryQnaServiceAsync>d__13.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.QnA.GenerateAnswerUtils.<GetAnswersRawAsync>d__9.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.QnA.QnAMaker.<GetAnswersRawAsync>d__22.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.AI.QnA.QnAMaker.<GetAnswersAsync>d__21.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at EchoBot3QnA.Bots.EchoBot.<AccessQnAMaker>d__10.MoveNext() in C:\Users\User1\~
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at EchoBot3QnA.Bots.EchoBot.<OnMessageActivityAsync>d__8.MoveNext() in C:\Users\User1\~
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.BotFrameworkAdapter.TenantIdWorkaroundForTeamsMiddleware.<OnTurnAsync>d__0.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.MiddlewareSet.<ReceiveActivityWithStatusAsync>d__3.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.BotAdapter.<RunPipelineAsync>d__15.MoveNext()
NativeErrorCode = 10060 System.Exception {System.Net.Sockets.SocketException}
"接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。" string
原因
ここにヒントがあるが、QnA Maker接続用のクラスMicrosoft.Bot.Builder.AI.QnA.QnAMaker
内部で使用しているHttpClientでプロキシが使用されていないため。
ここによれば、HttpClientHandlerを一度初期化すれば、以降はどのようにHttpClientでコネクションしても接続できるとある。しかし、.NET Core 2.1の問題なのか仕様が変更されたのか、QnAMakerモジュールの仕様かは不明だが、HttpClientHandlerを一度初期化するだけでは解決しない。
.NET Core 3.1で改善している可能性もあるが、検証できていない。
対策
Microsoft.Bot.Builder.AI.QnA.QnAMaker
のインスタンスを作成する際に、プロキシを設定した HttpClientを渡すように変更する。
また、環境でプロキシのアドレスが異なる場合も考えられるため、設定ファイルにプロキシのアドレスを持たせる。
- .NET Core 3.1では
HttpClient.DefaultProxy
を使用できる可能性もあるが、検証できていないため、設定ファイルに持たせる形としている - 開発時の環境の相違を考慮し、
appsetting.json
の「新しい場合はコピーする」プロパティを新しい場合はコピーする
としている
変更前
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"ScmType": "None",
"QnAKnowledgebaseId": "knowledge-base-id",
"QnAAuthKey": "qna-maker-resource-key",
"QnAEndpointHostName": "your-hostname" // This is a URL ending in /qnamaker
}
public QnAMaker EchoBotQnA { get; private set; }
public EchoBot(QnAMakerEndpoint endpoint)
{
// connects to QnA Maker endpoint for each turn
EchoBotQnA = new QnAMaker(endpoint);
}
変更後
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"ScmType": "None",
"ProxyAddress": "http://(プロキシのアドレス):(プロキシのポート)",
"QnAKnowledgebaseId": "knowledge-base-id",
"QnAAuthKey": "qna-maker-resource-key",
"QnAEndpointHostName": "your-hostname" // This is a URL ending in /qnamaker
}
public QnAMaker EchoBotQnA { get; private set; }
public EchoBot(IConfiguration configuration, QnAMakerEndpoint endpoint)
{
Configuration = configuration;
// connects to QnA Maker endpoint for each turn
var proxyAddress = Configuration.GetValue<string>($"ProxyAddress");
if (string.IsNullOrEmpty(proxyAddress))
{
EchoBotQnA = new QnAMaker(endpoint);
}
else
{
var httpClientHandler = new HttpClientHandler
{
// .NET Core 2.1では(HttpClient.DefaultProxy)がない(https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclient.defaultproxy?view=netcore-3.1)
Proxy = new WebProxy(proxyAddress, true),
UseProxy = true
};
var client = new HttpClient(httpClientHandler);
EchoBotQnA = new QnAMaker(endpoint, null, client);
}
}
Author And Source
この問題について(プロキシ環境下でBot Framework から QnA Makerを呼び出せない問題への対処), 我々は、より多くの情報をここで見つけました https://qiita.com/tfukumori/items/02fc6454221d7c8b48a7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .