配置函数的WebSocket连接
本章节介绍通过函数工作流控制台,配置函数的WebSocket连接。
WebSocket连接概述
在FunctionGraph中,可以通过配置APIG触发器,使函数能够响应WebSocket请求。配置完成后,相关联的函数可以作为一个Web服务器,处理WebSocket连接和消息,并将结果返回给客户端。适用于长连接、实时消息收发和实时数据监控等场景,能够实现高效的实时通信和数据交互。
使用WebSocket的计费方式与使用HTTP的计费方式完全一致,可以将WebSocket看作连接时间较长的HTTP调用。关于计费的更多信息,请参见函数工作流计费概述。
约束与限制
- 仅HTTP函数支持配置WebSocket,事件函数不支持配置。
- WebSocket配置当前仅支持“华东-上海一”区域使用。
- FunctionGraph在设置执行超时时间时,不区分WebSocket请求和HTTP请求。若WebSocket连接的持续时间超过设定的执行超时时间,该连接将被强制关闭,客户端将接收到1006状态码。
步骤一:创建HTTP函数
- 登录函数工作流控制台,在左侧的导航栏选择“函数 > 函数列表”。
- 单击右上方的“创建函数”,进入“创建函数”页面。
- 选择“创建空白函数”,参考表1配置函数信息。
表1 函数配置 参数
说明
取值样例
函数类型
选择函数类型,支持以下两种函数类型:
- 事件函数:通过特定事件触发的函数,通常为JSON格式的请求事件。
- HTTP函数:处理HTTP请求的函数,可以直接发送HTTP请求到URL触发函数执行,从而使用Web服务。仅FunctionGraph v2版本支持创建HTTP函数。
HTTP函数
区域
选择要部署代码的区域。
当前WebSocket配置仅支持“华东-上海一”区域。
华东-上海一
函数名称
填写函数名称,命名规则如下:
可包含字母、数字、下划线和中划线,长度不超过60个字符。以大/小写字母开头,以字母或数字结尾。
WebSocket-demo
企业项目
选择函数所属的企业项目。企业项目是一种云资源管理方式,企业项目管理服务提供统一的云资源按项目管理,以及项目内的资源管理、成员管理。
默认选择“default”,支持用户选择已创建的企业项目。如果没有开通企业管理服务,将无法看到企业项目选项。开通方法请参见如何开通企业项目。
default
委托
选择函数的委托。通过委托函数工作流来访问其他云服务,例如:如果函数需要访问LTS、VPC等服务,则必须选择包含所需服务权限的委托;若函数不访问任何云服务,则无需选择委托。
默认“未使用任何委托”,支持选择已创建的委托。
当华为云账号下无函数默认委托时,FunctionGraph提供快速创建默认委托“fgs_default_agency”的功能,详情请参见默认委托。
未使用任何委托
高级设置
- 函数访问公网:开启后允许函数访问公网上的服务,其公网访问带宽为用户间共享。
- 函数访问VPC内资源:开启时,函数将使用配置的VPC所绑定的网卡进行网络访问同时禁用函数工作流的默认网卡。
- 日志记录:启用日志功能后,函数运行过程中产生的日志会上报到云日志服务(LTS)。LTS将按需收取费用,具体请参见云日志服务价格详情。
函数访问公网:开启
函数访问VPC内资源:未开启
日志记录:未开启
- 配置完成后单击“创建函数”,页面跳转至函数详情配置页面。
步骤二:配置函数代码
- 在函数详情页的“代码”页签下,打开“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');
WebSocket Server监听的IP地址是127.0.0.1,监听的端口号默认值为8000端口。
- 在“bootstrap”文件中编写如下内容,完成后如图2所示。
/opt/function/runtime/nodejs12.13/rtsp/nodejs/bin/node $RUNTIME_CODE_ROOT/index.js
- 返回函数工作流控制台,如图3所示在左侧的导航栏选择“函数 > 依赖包管理”,单击“创建依赖包”。
- 下载WebSocket依赖包“wss-nodejs12”文件,在“创建依赖包”界面如图4所示上传并配置WebSocket依赖包信息,填写完成后单击“创建”。
表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访问对象复制所需的代码文件对象URL。
添加文件,并上传4下载的“wss-nodejs12”文件
描述
填写依赖包的描述说明。
-
- 返回“WebSocket-demo”函数详情页,在“代码”页签最下方的“代码依赖包”模块,单击“添加依赖包”。
- 在选择依赖包弹窗中,依赖包源选择“私有依赖包”,添加4创建的“depend-websocket”依赖包,单击“确定”完成依赖包添加。
- 选择“设置 > 高级设置”,如图5所示开启“WebSocket”参数开关。
步骤三:创建APIG专享版实例
请根据业务需要,参考创建APIG实例购买所需规格的专享版APIG实例。
步骤四:创建APIG触发器
- 选择“设置 > 触发器”,单击“创建触发器”,参考表4创建一个API 网关服务 (APIG专享版)触发器。
表4 APIG专享版触发器参数说明 参数
说明
取值样例
触发器类型
必选参数。
选择“API网关服务(APIG专享版)”。
API网关服务(APIG专享版)
实例
必选参数。
选择APIG专享版实例。若无实例,可单击“创建实例”完成创建。
apig-ws
API名称
必选参数。
填写专享版APIG触发器的名称。支持汉字、英文、数字和下划线,且只能以英文和汉字开头,3-64字符。
API_websocket_demo
分组
必选参数。
选择API分组。API分组可以视为一组API的集合,API提供方以API分组为单位,管理分组内的所有API。
若未创建分组,可单击“创建分组”完成创建,创建完成单击右侧
即可。
APIGroup_ws
发布环境
必选参数。
选择API的发布环境。API可以同时提供给不同的场景调用,如生产、测试或开发,选择“RELEASE”,才能调用。
若未创建环境,可单击“创建发布环境”完成创建。
RELEASE
安全认证
必选参数。
API认证方式有以下三种方式:
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
- 如图6所示,创建成功后单击已创建的触发器名称,进入APIG服务界面。
APIG触发器创建成功后,访问地址不会变更。
- 在API实例详情界面,如图7所示单击“编辑”,进入编辑API界面 。
- 单击“下一步”至“默认后端”页签,如图8所示配置API参数,单击“完成”。
- 后端服务类型:选择“FunctionGraph”。
- 网络架构:选择“V2”。(如没有此参数,请向APIG服务提交工单开启白名单配置)
- 调用类型:选择“Synchronous”。WebSocket场景下,API的后端调用类型只支持Synchronous同步调用。
- 返回API实例详情界面,如图9所示单击“发布最新版本”。
步骤五:测试函数
- 返回函数工作流控制台,进入函数详情页面,选择“设置 > 触发器”,复制APIG触发器的访问地址。
图10 复制APIG触发器URL
- 使用Postman测试函数的正确性。
- 在Postman中创建WebSocket请求。将APIG触发器的调用URL复制到Postman中,并将Scheme由HTTPS变更为WSS。
- 根据业务需求配置Params和Headers参数。
- 连接WebSocket,连接成功后即可发送消息,可查看消息接收情况。
- 超过执行超时时间后,会断开与WebSocket服务器的连接。
WebSocket相关说明
- 连接保活和超时重连
当WebSocket连接建立后,除连接持续时间超过设定的执行超时时间会导致连接断开外,函数工作流不会干预任何逻辑。若在存续期间,您的WebSocket连接在特定时段内无数据传输,该连接可能被网络中间节点(例如NAT网关)关闭。在该场景下,您需要利用WebSocket协议的Ping、Pong帧来保持连接活动或验证WebSocket连接的有效性。
若业务需求超出函数工作流所能提供的最大请求超时时间,或应用需要在运行期间保持逻辑上的连接稳定,建议在客户端代码中加入超时重连机制。可使用Reconnecting-WebSocket库或SocketIO库以实现该机制。
- 会话亲和性
FunctionGraph作为无服务器计算平台,其函数实例采用请求触发式生命周期管理。在高并发场景下,系统通过自动扩缩容机制创建多个实例副本以应对流量压力,但无法保证同一客户端的连续请求路由至固定实例。对于需要维持会话状态的WebSocket应用,推荐采用Redis、Kafka、数据库等外部存储系统实现跨实例的状态同步。
例如,在聊天室应用中,由于函数工作流无法保证所有用户同时连接到同一个函数实例,因此可以利用Redis的发布订阅功能来实现消息广播。当用户加入一个聊天室时,函数会订阅该聊天室对应的频道。当用户发送消息时,函数会将消息发布到Redis中该聊天室对应的频道。由于同一聊天室的所有用户都已订阅了该频道,因此所有用户都会接收到该消息。