

# 管理连接的用户和客户端应用程序：`$connect` 和 `$disconnect` 路由
<a name="apigateway-websocket-api-route-keys-connect-disconnect"></a>

以下部分介绍如何将 `$connect` 和 `$disconnect` 路由用于 WebSocket API。

**Topics**
+ [`$connect` 路由](#apigateway-websocket-api-routes-about-connect)
+ [从 `$connect` 路由传递连接信息](#apigateway-websocket-api-passing-connectionId-on-connect)
+ [`$disconnect` 路由](#apigateway-websocket-api-routes-about-disconnect)

## `$connect` 路由
<a name="apigateway-websocket-api-routes-about-connect"></a>

客户端应用程序通过发送 WebSocket 升级请求连接到 WebSocket API。如果请求成功，则在建立连接时会执行 `$connect` 路由。

由于 WebSocket 连接是有状态连接，因此您只能在 `$connect` 路由上配置授权。`AuthN`/`AuthZ` 仅在连接时执行。

在执行完与 `$connect` 路由关联的集成之前，升级请求处于待处理状态，将不会建立实际连接。如果 `$connect` 请求失败（例如，由于 `AuthN`/`AuthZ` 失败或集成失败），则不会建立连接。

**注意**  
如果授权在 `$connect` 上失败，则不会建立连接，客户端将收到 `401` 或 `403` 响应。

为 `$connect` 设置集成是可选的。在以下情况下，您应该考虑设置 `$connect` 集成：
+ 您希望使客户端能够使用 `Sec-WebSocket-Protocol` 字段指定子协议。有关示例代码，请参阅 [设置需要 WebSocket 子协议的 `$connect` 路由](websocket-connect-route-subprotocol.md)。
+ 您希望在客户端连接时收到通知。
+ 您希望限制连接或控制谁会连接。
+ 您希望后端使用回调 URL 将消息发送回客户端。
+ 您希望将每个连接 ID 和其他信息存储到数据库中（例如，Amazon DynamoDB）。

## 从 `$connect` 路由传递连接信息
<a name="apigateway-websocket-api-passing-connectionId-on-connect"></a>

 您可以使用代理和非代理集成将信息从 `$connect` 路由传递到数据库或其他 AWS 服务。

### 使用代理集成传递连接信息
<a name="websocket-connect-proxy-integration"></a>

您可以通过事件中的 Lambda 代理集成访问连接信息。使用其他 AWS 服务 或 AWS Lambda 函数发布到连接。

以下 Lambda 函数显示如何使用 `requestContext` 对象记录连接 ID、域名、阶段名和查询字符串。

------
#### [ Node.js ]

```
 export const handler = async(event, context) => {
    const connectId = event["requestContext"]["connectionId"]
    const domainName = event["requestContext"]["domainName"]
    const stageName = event["requestContext"]["stage"]
    const qs = event['queryStringParameters']
    console.log('Connection ID: ', connectId, 'Domain Name: ', domainName, 'Stage Name: ', stageName, 'Query Strings: ', qs )
    return {"statusCode" : 200}
};
```

------
#### [ Python ]

```
import json
import logging
logger = logging.getLogger()
logger.setLevel("INFO")


def lambda_handler(event, context):
    connectId = event["requestContext"]["connectionId"]
    domainName = event["requestContext"]["domainName"]
    stageName = event["requestContext"]["stage"]
    qs = event['queryStringParameters']
    connectionInfo = {
        'Connection ID': connectId,
        'Domain Name': domainName,
        'Stage Name': stageName,
        'Query Strings': qs}
    logging.info(connectionInfo)
    return {"statusCode": 200}
```

------

### 使用非代理集成传递连接信息
<a name="websocket-connect-non-proxy-integration"></a>
+ 您可以使用非代理集成访问连接信息。设置集成请求并提供 WebSocket API 请求模板。以下 [Velocity 模板语言（VTL）](https://velocity.apache.org/engine/devel/vtl-reference.html)映射模板提供了集成请求。此请求将以下详细信息发送给非代理集成：
  + 连接 ID
  + 域名
  + 阶段名称
  + 路径
  + 标头
  + 查询字符串

  此请求将连接 ID、域名、阶段名、路径、标头和查询字符串发送到非代理集成。

  ```
  {
      "connectionId": "$context.connectionId",
      "domain": "$context.domainName",
      "stage": "$context.stage",
      "params": "$input.params()"
  }
  ```

  有关设置数据转换的更多信息，请参阅[针对 API Gateway 中的 WebSocket API 的数据转换](websocket-api-data-transformations.md)。

  要完成集成请求，请为集成响应设置 `StatusCode: 200`。要了解有关设置集成响应的更多信息，请参阅[使用 API Gateway 控制台设置集成响应](apigateway-websocket-api-integration-responses.md#apigateway-websocket-api-integration-response-using-console)。

## `$disconnect` 路由
<a name="apigateway-websocket-api-routes-about-disconnect"></a>

在连接关闭后，会执行 `$disconnect` 路由。

连接可以由服务器或客户端关闭。由于连接在执行时已经关闭，因此 `$disconnect` 是最适合的事件。API Gateway 将尽最大努力将 `$disconnect` 事件传送到您的集成，但它不能保证交付。

后端可以使用 `@connections` API 启动断开连接。有关更多信息，请参阅 [在后端服务中使用 `@connections` 命令](apigateway-how-to-call-websocket-api-connections.md)。