
# 配置函数的WebSocket连接
本章节介绍通过函数工作流控制台，配置函数的WebSocket连接。
#### WebSocket连接概述
在FunctionGraph中，可以通过配置APIG触发器，使函数能够响应WebSocket请求。配置完成后，相关联的函数可以作为一个Web服务器，处理WebSocket连接和消息，并将结果返回给客户端。适用于长连接、实时消息收发和实时数据监控等场景，能够实现高效的实时通信和数据交互。
使用WebSocket的计费方式与使用HTTP的计费方式完全一致，可以将WebSocket看作连接时间较长的HTTP调用。关于计费的更多信息，请参见[函数工作流计费概述](https://support.huaweicloud.com/price-functiongraph/functiongraph_00_0001.html)。
#### 约束与限制
- **仅HTTP函数支持配置WebSocket，事件函数不支持配置。**
- WebSocket配置当前仅支持"华东-上海一"区域使用。
- FunctionGraph在设置执行超时时间时，不区分WebSocket请求和HTTP请求。若WebSocket连接的持续时间超过设定的执行超时时间，该连接将被强制关闭，客户端将接收到1006状态码。
 
#### 步骤一：创建HTTP函数
1. 登录[函数工作流控制台](https://console.huaweicloud.com/functiongraph/?locale=zh-cn)，在左侧的导航栏选择"函数 \> 函数列表"。
2. 单击右上方的"创建函数"，进入"创建函数"页面。
3. 选择"创建空白函数"，参考[表1]配置函数信息。
   
    表1函数配置 
   | 参数   | 说明                                                                                                                                                                                                                                                                                                                                                                                                          | 取值样例                                                             |
   |:---|:---|:---|
   | 函数类型 | 选择函数类型，配置WebSocket连接需创建HTTP函数： HTTP函数：处理HTTP请求的函数，可以直接发送HTTP请求到URL触发函数执行，从而使用Web服务。仅FunctionGraph v2版本支持创建HTTP函数。                                                                                                                                                                                                                                                     | HTTP函数                                                           |
   | 区域   | 选择要部署代码的区域。 当前WebSocket配置仅支持"华东-上海一"区域。                                                                                                                                                                                                                                                                                                                             | 华东-上海一                                                           |
   | 函数名称 | 填写函数名称，命名规则如下： 可包含字母、数字、下划线和中划线，长度不超过60个字符。以大/小写字母开头，以字母或数字结尾。                                                                                                                                                                                                                                                                                                     | WebSocket-demo                                                   |
   | 企业项目 | 选择函数所属的企业项目。企业项目是一种云资源管理方式，企业项目管理服务提供统一的云资源按项目管理，以及项目内的资源管理、成员管理。 默认选择"default"，支持用户选择已创建的企业项目。如果没有开通企业管理服务，将无法看到企业项目选项。开通方法请参见[如何开通企业项目](https://support.huaweicloud.com/usermanual-em/eps_15_0001.html)。                                                                                                                                                          | default                                                          |
   | 委托   | 选择函数的委托。通过委托函数工作流来访问其他云服务，例如：如果函数需要访问LTS、VPC等服务，则必须选择包含所需服务权限的委托；若函数不访问任何云服务，则无需选择委托。 默认"未使用任何委托"，支持选择已创建的委托。 当华为云账号下无函数默认委托时，FunctionGraph提供快速创建默认委托"fgs_default_agency"的功能，详情请参见[默认委托](https://support.huaweicloud.com/usermanual-functiongraph/functiongraph_01_0920.html#functiongraph_01_0920__section102217211358)。 | 未使用任何委托                                                          |
   | 高级设置 | - 函数访问公网：开启后允许函数访问公网上的服务，其公网访问带宽为用户间共享。  - 函数访问VPC内资源：开启时，函数将使用配置的VPC所绑定的网卡进行网络访问同时禁用函数工作流的默认网卡。                                                                                                      | 函数访问公网：开启 函数访问VPC内资源：未开启 |
      
   
   
4. 配置完成后单击"创建函数"，页面跳转至函数详情配置页面。
 
#### 步骤二：配置函数代码
1. 在函数详情页的"代码"页签下，打开"index.js"文件，使用代码编辑器复制以下代码并部署，部署完成后如[图1]所示。
   
   ```
   const WebSocket = require('ws'); 
   const WebSocketServer = WebSocket.Server;  
   const wss = new WebSocketServer({     
       host: '127.0.0.1',     
       port: 8000,     
       path: '/websocket_demo' 
   });  
   // 用于存储所有已连接的客户端 
   const clients = new Set(); 
   wss.on('connection', function connection(ws) {     
       // 当有客户端连接时，添加到客户端集合中     
       clients.add(ws);     
       console.log('Client connected');      
       // 处理客户端发送的消息     
       ws.on('message', function incoming(message) {         
           console.log('received: %s', message);     
       });      
       // 处理连接关闭     
       ws.on('close', () => {         
           console.log('Client disconnected');         
           // 从集合中移除断开连接的客户端         
           clients.delete(ws);     
       }); 
   });  
   // 定时向所有客户端发送消息 
   setInterval(() => {     
       // 遍历所有客户端并发送消息     
       for (let ws of clients) {         
           if (ws.readyState === WebSocket.OPEN) {             
               ws.send('Server time: ' + new Date().toTimeString());         
           }     
       } 
   }, 2000); // 每2秒执行一次  
   console.log('WebSocket server is running on ws://127.0.0.1:8000/websocket_demo');
   ```
   图1index.js文件   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002240129510.png "点击放大")
   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/public_sys-resources/note_3.0-zh-cn.png)
   WebSocket Server监听的IP地址是127.0.0.1，监听的端口号默认值为8000端口。
   
   
2. 在"bootstrap"文件中编写如下内容，完成后如[图2]所示。
   
   ```
   /opt/function/runtime/nodejs12.13/rtsp/nodejs/bin/node $RUNTIME_CODE_ROOT/index.js
   ```
   图2bootstrap文件   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002240297540.png "点击放大")
   
   
3. 返回函数工作流控制台，如[图3]所示在左侧的导航栏选择"函数 \> 依赖包管理"，单击"创建依赖包"。
   
   图3依赖包管理   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002278004504.png "点击放大")
   
   
   
4. [下载WebSocket依赖包](https://functionstage-community.obs.cn-north-1.myhuaweicloud.com/others/wss-nodejs12.zip)"wss-nodejs12"文件，在"创建依赖包"界面如[图4]所示上传并配置WebSocket依赖包信息，填写完成后单击"创建"。
   
   图4创建依赖包   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002312773277.png "点击放大")
   
   表2创建依赖包 
   | 参数         | 参数说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 取值样例                                                                 |
   |:---|:---|:---|
   | 依赖包名称      | 自定义填写依赖包的名称。 以大/小写字母开头，以字母或数字结尾。 可包含字母、数字、下划线、点和中划线，长度不超过96个字符。                                                                                                                                                                                                                                                                                                                                   | depend-websocket                                                     |
   | 运行时        | 选择依赖包的运行时。                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Node.js 12.13                                                        |
   | 代码上传方式     | 选择代码上传方式。支持"上传ZIP文件"或通过OBS链接"从OBS上传文件"。                                                                                                                                                                                                                                                                                                                                                                                                                                         | 上传ZIP文件                                                              |
   | 文件上传/OBS链接 | - 代码上传方式为"上传ZIP文件"：单击"添加文件"上传打包为ZIP格式文件的依赖包。上传的ZIP文件大小限制为10M，超过10M请使用从OBS上传文件。  - 代码上传方式为"从OBS上传文件"：填写指向代码文件对象的OBS对象URL，需将对象放入与函数在同一区域下的OBS桶中，该对象必须为ZIP格式文件。可参考[通过URL访问OBS对象](https://support.huaweicloud.com/usermanual-obs/obs_03_0319.html)复制所需的代码文件对象URL。   | 添加文件，并上传[4]下载的"wss-nodejs12"文件 |
   | 描述         | 填写依赖包的描述说明。                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | -                                                                    |
      
   
   
5. 返回"WebSocket-demo"函数详情页，在"代码"页签最下方的"代码依赖包"模块，单击"添加依赖包"。
6. 在选择依赖包弹窗中，依赖包源选择"私有依赖包"，添加[4]创建的"depend-websocket"依赖包，单击"确定"完成依赖包添加。
7. 选择"设置 \> 高级设置"，如[图5]所示开启"WebSocket"参数开关。
   
   图5开启WebSocket   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002278241468.png "点击放大")
   
   
   
 
#### 步骤三：创建APIG专享版实例
请根据业务需要，参考[创建APIG实例](https://support.huaweicloud.com/usermanual-apig/apig_03_0037.html)购买所需规格的专享版APIG实例。
购买过程中请参照以下注意事项：
表3创建APIG实例注意事项 
| 参数   | 说明                                                                                                                                                                                                                                                                                                                                                       |
|:---|:---|
| 区域   | 选择与所创建函数一致的区域。                                                                                                                                                                                                                                                                                                                                           |
| 公网入口 | - 如使用[步骤五：测试函数]进行本地测试，则需"开启公网入口"，请根据实际需求选择入公网带宽。  - 如在生产环境中使用VPC内访问函数的WebSocket特性，则无需"开启公网入口"。   |
| 网络   | 如在生产环境中使用可[配置函数访问VPC](https://support.huaweicloud.com/usermanual-functiongraph/functiongraph_01_0222.html#functiongraph_01_0222__section923421213196)，并在此参数中配置与函数相同的VPC与子网。                                                                                                                                                                              |
   
#### 步骤四：创建APIG触发器
1. 选择"设置 \> 触发器"，单击"创建触发器"，参考[表4]创建一个API 网关服务 (APIG专享版）触发器。
   
    表4APIG专享版触发器参数说明 
   | 参数       | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | 取值样例               |
   |:---|:---|:---|
   | 触发器类型    | 必选参数。 选择"API网关服务（APIG专享版）"。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | API网关服务（APIG专享版）   |
   | 实例       | 必选参数。 选择APIG专享版实例。若无实例，可单击"创建实例"完成创建。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | apig-ws            |
   | API名称    | 必选参数。 填写专享版APIG触发器的名称。支持汉字、英文、数字和下划线，且只能以英文和汉字开头，3-64字符。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | API_websocket_demo |
   | 分组       | 必选参数。 选择API分组。API分组可以视为一组API的集合，API提供方以API分组为单位，管理分组内的所有API。 若未创建分组，可单击"创建分组"完成创建，创建完成单击右侧![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002340922265.png "点击放大")即可。                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | APIGroup_ws        |
   | 发布环境     | 必选参数。 选择API的发布环境。API可以同时提供给不同的场景调用，如生产、测试或开发，选择"RELEASE"，才能调用。 若未创建环境，可单击"创建发布环境"完成创建。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | RELEASE            |
   | 安全认证     | 必选参数。 API认证方式有以下三种方式： - App： 采用Appkey\&Appsecret认证，安全级别高，推荐使用，详情请参见[APP认证](https://support.huaweicloud.com/devg-apig/apig-dev-180307002.html)。  - IAM： IAM认证，只允许IAM用户能访问，安全级别中等，详情请参见[IAM认证](https://support.huaweicloud.com/devg-apig/apig-dev-180307020.html)。  - None： 无认证模式，所有用户均可访问。 注意： 当前示例中安全认证选择"None"，实际业务使用推荐选择安全级别高的认证方式。    | None               |
   | 请求协议     | 必选参数。 在使用WebSocket时HTTPS对应WSS，HTTP对应WS。 API的请求协议分为两种类型： - HTTP：数据在传输过程中不被加密。  - HTTPS：数据在传输过程中被加密。                                                                                                                                                                                                                                                                                                                     | HTTPS              |
   | 请求方法     | 必选参数。 如需使用WebSocket协议，请求方法至少需要支持GET。 支持的请求方法：GET、POST、DELETE、PUT、PATCH、HEAD、OPTIONS、ANY。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | GET                |
   | 后端超时(毫秒) | 必选参数。 设置API的后端超时时间，单位为毫秒，设置范围为1\~60000毫秒。 后端超时时间表示WebSocket的**最大空闲连接时间**，例如设置为5000毫秒，即当WebSocket超过5000毫秒未收发消息时，连接断开。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | 5000               |
      
   
   
2. 如[图6]所示，创建成功后单击已创建的触发器名称，进入APIG服务界面。
   
   图6APIG触发器   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002341088329.png "点击放大")
   ![](https://support.huaweicloud.com/usermanual-functiongraph/public_sys-resources/note_3.0-zh-cn.png)
   APIG触发器创建成功后，访问地址不会变更。
   
   
   
3. 在API实例详情界面，如[图7]所示单击"编辑"，进入编辑API界面 。
   
   图7编辑API   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002312915501.png "点击放大")
   
   
   
4. 单击"下一步"至"默认后端"页签，如[图8]所示配置API参数，单击"完成"。
   
   - 后端服务类型：选择"FunctionGraph"。
   
   - 网络架构：选择"V2"。（如没有此参数，请向APIG服务[提交工单](https://console.huaweicloud.com/ticket/?agencyId=e4ebeeb18baa4ae58946b5342fa6159d#/ticketindex/createIndex)开启白名单配置）
   
   - 调用类型：选择"Synchronous"。WebSocket场景下，API的后端调用类型只支持Synchronous同步调用。
     其他参数保持默认即可。
     图8编辑API默认后端   
     ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002278427970.png "点击放大") 
   
   
   
   
   
5. 返回API实例详情界面，如[图9]所示单击"发布最新版本"。
   
   图9发布最新版本api   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002278436106.png "点击放大")
   
   
   
 
 #### 步骤五：测试函数
1. 返回函数工作流控制台，进入函数详情页面，选择"设置 \> 触发器"，复制APIG触发器的访问地址。 
   图10复制APIG触发器URL   
   ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002307009998.png "点击放大")
   
   
   
2. 使用Postman测试函数的正确性。 
   1. 在Postman中创建WebSocket请求。将APIG触发器的调用URL复制到Postman中，并将Scheme由HTTPS变更为WSS。
   
   2. 根据业务需求配置Params和Headers参数。
   
   3. 连接WebSocket，连接成功后即可发送消息，可查看消息接收情况。
   
   4. 超过执行超时时间后，会断开与WebSocket服务器的连接。
      图11WebSocket测试   
      ![](https://support.huaweicloud.com/usermanual-functiongraph/zh-cn_image_0000002323626185.png "点击放大") 
   
   
   
   
 
#### WebSocket相关说明
- **连接保活和超时重连**
  当WebSocket连接建立后，除连接持续时间超过设定的执行超时时间会导致连接断开外，函数工作流不会干预任何逻辑。若在存续期间，您的WebSocket连接在特定时段内无数据传输，该连接可能被网络中间节点（例如NAT网关）关闭。在该场景下，您需要利用WebSocket协议的Ping、Pong帧来保持连接活动或验证WebSocket连接的有效性。
  若业务需求超出函数工作流所能提供的最大请求超时时间，或应用需要在运行期间保持逻辑上的连接稳定，建议在客户端代码中加入超时重连机制。可使用[Reconnecting-WebSocket](https://github.com/joewalnes/reconnecting-websocket/)库或[SocketIO](https://socket.io/docs/v3/server-socket-instance#disconnect)库以实现该机制。
  
- **会话亲和性**
  FunctionGraph作为无服务器计算平台，其函数实例采用请求触发式生命周期管理。在高并发场景下，系统通过自动扩缩容机制创建多个实例副本以应对流量压力，但无法保证同一客户端的连续请求路由至固定实例。对于需要维持会话状态的WebSocket应用，推荐采用Redis、Kafka、数据库等外部存储系统实现跨实例的状态同步。
  例如，在聊天室应用中，由于函数工作流无法保证所有用户同时连接到同一个函数实例，因此可以利用Redis的发布订阅功能来实现消息广播。当用户加入一个聊天室时，函数会订阅该聊天室对应的频道。当用户发送消息时，函数会将消息发布到Redis中该聊天室对应的频道。由于同一聊天室的所有用户都已订阅了该频道，因此所有用户都会接收到该消息。
  
 
