C# 对话总是在Directline BOT频道websocket中重新启动,如何保持对话畅通?
我已经建立了一个应用程序,需要连接到机器人DirectLine-websockets频道,通过LUIS和Twilio的短信进行对话。 为了让机器人与应用程序对话,我编写了一个mvc控制器来传递消息。 我不确定这种方法是否正确,我是根据一些样品制作的。 它可以工作,但主要的问题是,当从客户端收到消息时,我的代码似乎总是启动一个新的对话,因此上下文没有得到维护。 我怎样才能保持对话流畅,而不是每次都重新开始? 我的意思是,步骤应该是,例如:C# 对话总是在Directline BOT频道websocket中重新启动,如何保持对话畅通?,c#,botframework,twilio-api,azure-language-understanding,direct-line-botframework,C#,Botframework,Twilio Api,Azure Language Understanding,Direct Line Botframework,我已经建立了一个应用程序,需要连接到机器人DirectLine-websockets频道,通过LUIS和Twilio的短信进行对话。 为了让机器人与应用程序对话,我编写了一个mvc控制器来传递消息。 我不确定这种方法是否正确,我是根据一些样品制作的。 它可以工作,但主要的问题是,当从客户端收到消息时,我的代码似乎总是启动一个新的对话,因此上下文没有得到维护。 我怎样才能保持对话流畅,而不是每次都重新开始? 我的意思是,步骤应该是,例如: 机器人:你好,你叫什么名字? 用户:卡尔 机器人:很高兴
机器人:你好,你叫什么名字?
用户:卡尔
机器人:很高兴认识你,卡尔
相反,我得到:
机器人:你好,你叫什么名字?
用户:卡尔
对不起,我帮不了你。
就像对话是从头开始的 这是我的控制器代码(Twilio webhook设置为):
公共类smsappController:TwilioController
{
私有静态字符串directLineSecret=ConfigurationManager.AppSettings[“directLineSecret”];
私有静态字符串botId=ConfigurationManager.AppSettings[“botId”];
常量字符串accountSid=“模糊化”;
常量字符串authToken=“模糊化”;
私有静态字符串fromUser=“DirectLineSampleClientUser”;
私有字符串SMSreply=“”;
公共异步任务索引(SmsRequest incomingMessage)
{
//使用直连密码获取令牌
var tokenResponse=等待新的DirectLineClient(directLineSecret).Tokens.GenerateTokenForNewConversationAsync();
//使用令牌创建对话
var directLineClient=新的directLineClient(tokenResponse.Token);
var conversation=wait directLineClient.Conversations.StartConversationAsync();
使用(var webSocketClient=newwebsocket(conversation.StreamUrl))
{
webSocketClient.OnMessage+=webSocketClient_OnMessage;
//您必须将TLS版本指定为1.2,否则握手时连接将失败。
webSocketClient.SslConfiguration.enabledslprotocols=System.Security.Authentication.SslProtocols.Tls12;
webSocketClient.Connect();
while(true)
{
字符串输入=incomingMessage.Body;
如果(!string.IsNullOrEmpty(输入))
{
if(input.ToLower()=“退出”)
{
打破
}
其他的
{
如果(input.Length>0)
{
Activity userMessage=新活动
{
From=新的渠道帐户(fromUser),
文本=输入,
类型=ActivityTypes.Message
};
等待directLineClient.Conversations.PostActivitySync(conversation.ConversationId,userMessage);
//中断;
如果(!string.IsNullOrEmpty(SMSreply))
{
var messagingResponse=新messagingResponse();
var message=messagingResponse.AddChild(“消息”);
message.AddText(SMSreply);//发送文本
SMSreply=string.Empty;
返回TwiML(messagingResponse);
}
}
}
}
}
}
返回null;
}
私有void WebSocketClient_OnMessage(对象发送者,MessageEventArgs e)
{
//有时,直拨电话服务会发送一条空消息作为活动ping。忽略这些消息。
如果(!string.IsNullOrWhiteSpace(e.Data))
{
var activitySet=JsonConvert.DeserializeObject(即数据);
var activities=来自activitySet.activities中的x
其中x.From.Id==botId
选择x;
foreach(活动中的活动)
{
如果(!string.IsNullOrEmpty(activity.Text))
{
SMSreply=activity.Text;
}
}
}
}
}
问题实际上是我没有保存和检索conversationID。
目前,我正在使用静态变量来存储值进行测试。
然后我重新连接到与它的对话,与bot的对话保持在上下文中 问题实际上是我没有保存和检索conversationID。 目前,我正在使用静态变量来存储值进行测试。
然后我重新连接到与它的对话,与bot的对话保持在上下文中 我有很多问题。当你说“botdirectline-websockets频道”的时候,你是在说直拨电话还是仅仅是直拨电话?为什么你创建了一个中间应用程序来在Twilio和Direct Line之间转发消息,而不仅仅是使用Twilio频道?您是否已验证bot是否正确保存其对话框状态?您是否已验证应用程序发送到bot的活动实际上具有相同的用户ID和对话ID?Directline,而不是speech。因为我需要频道尽可能地为将来的发展定制(例如语音)。问题是我没有保存和检索conversationID。所以你已经解决了问题?您想把它作为一个答案发布,这样您就可以接受它了吗?目前,我将conversationID存储在一个静态变量中。关于存储它的最佳做法,您有什么建议吗?谢谢你,有了这段代码,我在第一次看到我的时候也遇到了超时的问题
public class smsappController : TwilioController
{
private static string directLineSecret = ConfigurationManager.AppSettings["DirectLineSecret"];
private static string botId = ConfigurationManager.AppSettings["BotId"];
const string accountSid = "obfuscated";
const string authToken = "obfuscated";
private static string fromUser = "DirectLineSampleClientUser";
private string SMSreply = "";
public async Task<TwiMLResult> Index(SmsRequest incomingMessage)
{
// Obtain a token using the Direct Line secret
var tokenResponse = await new DirectLineClient(directLineSecret).Tokens.GenerateTokenForNewConversationAsync();
// Use token to create conversation
var directLineClient = new DirectLineClient(tokenResponse.Token);
var conversation = await directLineClient.Conversations.StartConversationAsync();
using (var webSocketClient = new WebSocket(conversation.StreamUrl))
{
webSocketClient.OnMessage += WebSocketClient_OnMessage;
// You have to specify TLS version to 1.2 or connection will be failed in handshake.
webSocketClient.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;
webSocketClient.Connect();
while (true)
{
string input = incomingMessage.Body;
if (!string.IsNullOrEmpty(input))
{
if (input.ToLower() == "exit")
{
break;
}
else
{
if (input.Length > 0)
{
Activity userMessage = new Activity
{
From = new ChannelAccount(fromUser),
Text = input,
Type = ActivityTypes.Message
};
await directLineClient.Conversations.PostActivityAsync(conversation.ConversationId, userMessage);
//break;
if (!string.IsNullOrEmpty(SMSreply))
{
var messagingResponse = new MessagingResponse();
var message = messagingResponse.AddChild("Message");
message.AddText(SMSreply); //send text
SMSreply = string.Empty;
return TwiML(messagingResponse);
}
}
}
}
}
}
return null;
}
private void WebSocketClient_OnMessage(object sender, MessageEventArgs e)
{
// Occasionally, the Direct Line service sends an empty message as a liveness ping. Ignore these messages.
if (!string.IsNullOrWhiteSpace(e.Data))
{
var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data);
var activities = from x in activitySet.Activities
where x.From.Id == botId
select x;
foreach (Activity activity in activities)
{
if (!string.IsNullOrEmpty(activity.Text))
{
SMSreply = activity.Text;
}
}
}
}
}