你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Direct Line API 3.0 中从机器人接收活动

使用 Direct Line 3.0 协议,客户端可以通过 WebSocket 流接收活动或通过发出 HTTP GET 请求来检索活动。

WebSocket 和 HTTP GET

流式处理 WebSocket 有效地将消息推送到客户端,而 GET 接口可使客户端显式请求消息。 尽管 WebSocket 机制由于其效率通常是首选机制,但 GET 机制对于无法使用 WebSocket 的客户端非常有用。

该服务只允许每个对话存在 1 个 WebSocket 连接。 Direct Line 可能会关闭其他 WebSocket 连接,原因值为 collision

并非所有活动类型都可通过 WebSocket 和 HTTP GET 获得。 下表介绍了使用 Direct Line 协议的客户端的各种活动类型的可用性。

活动类型 可用性
message HTTP GET 和 WebSocket
typing 仅 WebSocket
conversationUpdate 未通过客户端发送/接收
contactRelationUpdate Direct Line 不受支持
endOfConversation HTTP GET 和 WebSocket
所有其他活动类型 HTTP GET 和 WebSocket

通过 WebSocket 流接收活动

当客户端发送启动会话请求以打开与机器人的会话时,该服务的响应包括客户端随后可以通过 WebSocket 连接的 streamUrl 属性。 流 URL 是预先授权的,因此客户端通过 WebSocket 连接的请求不需要 Authorization 标头。

下面的示例演示使用 streamUrl 通过 WebSocket 进行连接的请求。

-- connect to wss://directline.botframework.com --
GET /v3/directline/conversations/abc123/stream?t=RCurR_XV9ZA.cwA..."
Upgrade: websocket
Connection: upgrade
[other headers]

该服务以状态代码 HTTP 101(“交换协议”)响应。

HTTP/1.1 101 Switching Protocols
[other headers]

接收消息

通过 WebSocket 连接后,客户端可能会从 Direct Line 服务接收以下类型的消息:

  • 包含 ActivitySet 的消息,其中包含一个或多个活动和水印(如下所述)。
  • 一条空消息,Direct Line 服务使用该消息来确保连接仍然有效。
  • 其他类型,以便稍后进行定义。 这些类型由 JSON 根中的属性标识。

ActivitySet 包含机器人和会话中所有用户发送的消息。 以下示例显示包含单个消息的 ActivitySet

{
    "activities": [
        {
            "type": "message",
            "channelId": "directline",
            "conversation": {
                "id": "abc123"
            },
            "id": "abc123|0000",
            "from": {
                "id": "user1"
            },
            "text": "hello"
        }
    ],
    "watermark": "0000a-42"
}

处理消息

客户端应该跟踪它在每个 ActivitySet 中接收的 watermark 值,以便它可以使用水印来保证在丢失连接并且需要重新连接到会话时不丢失任何消息。 如果客户端收到 ActivitySet,其中 watermark 属性为 null 或缺失,则应忽略该值并且不覆盖以前收到的水印。

客户端应忽略从 Direct Line 服务接收的空消息。

客户端可以向 Direct Line 服务发送空消息以验证连接。 Direct Line 服务将忽略它从客户端接收的空消息。

Direct Line 服务可能会在某些条件下强行关闭 WebSocket 连接。 如果客户端尚未收到 endOfConversation 活动,则可以生成新 WebSocket 流 URL,该 URL 可用于重新连接到会话。

WebSocket 流包含实时更新和最近 (消息,因为通过 WebSocket 进行连接的调用是) 但不包括在最近 POST 发送到 /v3/directline/conversations/{id}之前发送的消息。 若要检索之前在会话中发送的消息,请使用 HTTP GET,如下所述。

使用 HTTP GET 检索活动

无法使用 WebSocket 的客户端可以通过 HTTP GET 检索活动。

若要检索特定聊天的消息,请向 /v3/directline/conversations/{conversationId}/activities 终结点发出 GET 请求,根据需要指定 watermark 参数以指示客户端看到的最新消息。

以下代码片段提供了 Get Conversation Activities 请求和响应的示例。 Get Conversation Activities 响应包含作为 ActivitySet 的属性的 watermark。 客户端应通过增加 watermark 值来浏览可用活动,直到不返回任何活动。

请求

GET https://directline.botframework.com/v3/directline/conversations/abc123/activities?watermark=0001a-94
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0

响应

HTTP/1.1 200 OK
[other headers]
{
    "activities": [
        {
            "type": "message",
            "channelId": "directline",
            "conversation": {
                "id": "abc123"
            },
            "id": "abc123|0000",
            "from": {
                "id": "user1"
            },
            "text": "hello"
        }, 
        {
            "type": "message",
            "channelId": "directline",
            "conversation": {
                "id": "abc123"
            },
            "id": "abc123|0001",
            "from": {
                "id": "bot1"
            },
            "text": "Nice to see you, user1!"
        }
    ],
    "watermark": "0001a-95"
}

计时注意事项

大多数客户端都想要保留完整的消息历史记录。 尽管 Direct Line 是一个具有潜在计时间隙的多部分协议,但协议和服务旨在轻松简单地生成可靠的客户端。

  • 在 WebSocket 流和 Get Conversation Activities 响应中发送的 watermark 属性是可靠的。 只要客户端逐字重播水印,客户端就不会错过任何消息。

  • 当客户端启动会话并连接到 WebSocket 流时,在 POST 之后但在打开套接字之前发送的任何活动都将在新活动之前重播。

  • 当客户端在连接到 WebSocket 流时发出获取对话活动请求 (刷新历史记录) 时,活动可能会跨两个通道重复。 客户端应跟踪所有已知活动 ID,以便在发生重复活动时能够拒绝重复活动。

使用 HTTP GET 轮询的客户端应选择与其预期用途相匹配的轮询间隔。

  • 服务到服务应用程序通常使用 5 秒或 10 秒的轮询间隔。

  • 面向客户端的应用程序通常使用 1 秒的轮询间隔,并在客户端发送每条消息之后很快发出单个额外的请求(以快速检索机器人的响应)。 此延迟可以低至 300 毫秒,但应该根据机器人的速度和传输时间进行调整。 在任何长时间内,轮询的频率不应超过每秒一次。

其他资源