首页 > 解决方案 > 设置 Activity.Typing 动画的时间

问题描述

我正在尝试在从服务器获取数据期间创建一些动画。“打字”活动似乎是合理的,但它只工作约 4 秒:

Activity reply = activity.CreateReply();
reply.Type = ActivityTypes.Typing;
reply.Text = null;
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);

我试图做异步监听:

while (!_fetchEnded)
{
   await connector.Conversations.ReplyToActivityAsync(reply);
   Thread.Sleep(3000);
}

但它会产生滞后行为。是否有可能设置“打字”活动的持续时间或其他方式来防止打开和关闭打字?

标签: c#botframework

解决方案


默认情况下,键入仅显示几秒钟。您可以通过以较低频率再次发送打字事件来强制显示打字指示器。

实现示例,它将每 2 秒发送一次事件,最长 30 秒:

public async Task<HttpResponseMessage> Post([FromBody]Microsoft.Bot.Connector.Activity activity, CancellationToken token)
{
    // Send Typing messages
    var typingCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));
    var typingTask = SendTypingActivityUntilCancellation(activity, TimeSpan.FromSeconds(2), typingCancellation.Token);

    try
    {
        // Activity treatment
        if (activity.Type == ActivityTypes.Message)
        {
            // ...
        }
        else if (activity.Type == ActivityTypes.Event && activity.ChannelId == ChannelEnum.directline.ToString())
        {
            // ...
        }

        typingCancellation.Cancel();
        await typingTask;
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    catch (Exception e)
    {
        typingCancellation.Cancel();
        await typingTask;
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
}

public async Task SendTypingActivityUntilCancellation(Activity activity, TimeSpan period, CancellationToken cancellationtoken)
{
    try
    {
        var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
        Activity isTypingReply = activity.CreateReply();
        isTypingReply.Type = ActivityTypes.Typing;

        do
        {
            if (cancellationtoken.IsCancellationRequested == false)
            {
                await connector.Conversations.ReplyToActivityAsync(isTypingReply);
            }

            // Check again if token has not been canceled during the reply delay
            if (cancellationtoken.IsCancellationRequested == false)
            {
                await Task.Delay(period);
            }
        }
        while (cancellationtoken.IsCancellationRequested == false);
    }
    catch (OperationCanceledException)
    {
        //nothing to do.
    }
}

推荐阅读