# WebSocket
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
# 功能概述
HTTP协议是一种无状态、单向的请求-响应协议,客户端只能通过主动发送请求获取服务器数据。在实时性要求较高的场景(如在线聊天、实时监控)中,应用若基于HTTP协议实现实时通信,通常需采用轮询(Polling)或长轮询(Long Polling)机制来模拟。然而,这种方式会产生大量额外的网络请求,不仅增加带宽消耗和服务器负担,也难以保证数据传输的实时性。
WebSocket协议为解决上述问题而设计:它在单个TCP连接上实现全双工通信,客户端与服务器建立持久连接后,即可实现数据的实时双向传输。本文档将介绍WebSocket的基本概念,并详细说明WebSocket相关的API,包括参数配置、连接管理、数据收发、状态查询等功能,以及相关的结构体和枚举定义。
## 基本概念
WebSocket是一种基于TCP的应用层通信协议,于2011年由IETF标准化为RFC 6455。它实现了客户端与服务器之间的全双工(Full-Duplex)通信:连接建立后,双方可同时向对方发送数据,无需像HTTP协议那样每次通信都由客户端发起请求。
WebSocket协议的设计目标是在Web环境中提供低延迟、高实时性的数据传输服务。在握手阶段通过一次HTTP请求完成协议升级,握手成功后即可切换为WebSocket协议传输数据,不再依赖HTTP。
**核心特点:**
- **全双工通信**:连接建立后,客户端与服务器可同时向对方发送数据,不受HTTP协议单向请求-响应模式的限制,满足实时通信的需求。
- **持久连接**:连接建立后会保持打开状态,直到客户端或服务器主动关闭,减少了反复建立和断开连接的开销,适用于频繁传输数据的场景。
- **低开销**:仅在建立连接时使用HTTP协议进行握手,此后的数据传输不再携带HTTP头部信息,每帧仅附加少量帧头数据,协议开销小。
- **二进制数据传输**:除文本数据外,WebSocket支持直接传输图片、音频、视频等二进制数据。
## 协议栈
```{image} images/image_RubwbGRSxooD4Dx7VxFctGfzn1c.webp
:width: 705px
:height: 245px
:align: center
```
WebSocket是独立的应用层协议,仅在建立连接阶段借用HTTP完成握手,其后通信不再依赖HTTP。
## 通信流程
```{image} images/image_Hvgfb3lv7oPp9Exy1LUcDXvjnZg.webp
:width: 814px
:height: 448px
:align: center
```
# WebSocket API
## 头文件
*qcm_WebSocket.h*
## 函数概览
| **函数** | **说明** |
| --- | --- |
| *qcm_ws_cfg_set()* | 设置指定的Web服务配置项 |
| *qcm_ws_cfg_get()* | 获取指定的Web服务配置项 |
| *qcm_ws_cfg_set_all()* | 设置指定配置ID的所有Web配置信息 |
| *qcm_ws_cfg_get_all()* | 获取指定配置ID的所有Web配置信息 |
| *qcm_ws_open_proc()* | 初始化并打开一个WebSocket连接 |
| *qcm_ws_close_proc()* | 关闭指定客户端ID对应的WebSocket连接 |
| *qcm_ws_read_proc()* | 读取指定客户端的数据到缓冲区 |
| *qcm_ws_write_proc()* | 写入数据到指定的WebSocket客户端 |
| *qcm_ws_client_get_curr_conn_status()* | 获取当前的WebSocket连接状态和客户端状态 |
| *qcm_ws_client_get_send_size()* | 获取通过TX通道发送至模块的数据总量,以及通过 *send()* 成功发送的数据量 |
## 函数详解
### qcm_ws_cfg_set
- **功能描述**
设置指定的Web服务配置项。
- **函数原型**
```c
qcm_web_err_e qcm_ws_cfg_set(int config_id, qcm_web_cfg_e opt_tag, void *ptr, int value);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *config_id* | 输入 | int | 要操作的配置ID;0~(最大并发数-1);默认值:0 |
| *opt_tag* | 输入 | *qcm_web_cfg_e* | 配置选项标签,指定要设置的具体配置项;详见 [*qcm_web_cfg_e*](#qcmwebcfg_e) |
| *ptr* | 输入 | void * | 配置参数的缓冲区指针,用于传入配置项的具体数据 |
| *value* | 输入 | int | 配置参数的辅助数值,可用于标识数据长度或其他补充信息 |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_cfg_get
- **功能描述**
获取指定的Web服务配置项。
- **函数原型**
```c
qcm_web_err_e qcm_ws_cfg_get(int config_id, qcm_web_cfg_e opt_tag, qcm_web_cfg_t *cfg);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *config_id* | 输入 | int | 要操作的配置ID;0~(最大并发数-1);默认值:0 |
| *opt_tag* | 输入 | *qcm_web_cfg_e* | 配置选项标签,指定要获取的具体配置项;详见 [*qcm_web_cfg_e*](#qcmwebcfg_e) |
| *cfg* | 输出 | *qcm_web_cfg_t** | 配置参数的缓冲区指针,用于返回获取到的配置数据;详见 [*qcm_web_cfg_t*](#qcmwebcfg_t) |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_cfg_set_all
- **功能描述**
设置指定配置ID的所有Web配置信息。
- **函数原型**
```c
qcm_web_err_e qcm_ws_cfg_set_all(int config_id, const qcm_web_config_t *new_config);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *config_id* | 输入 | int | 要操作的配置ID;0~(最大并发数-1);默认值:0 |
| *new_config* | 输入 | *const qcm_web_config_t** | 指向新配置结构体的指针,包含所有要设置的Web服务配置参数;详见 [*qcm_web_config_t*](#qcmwebconfig_t) |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_cfg_get_all
- **功能描述**
获取指定配置ID的所有Web配置信息。
- **函数原型**
```c
qcm_web_config_t *qcm_ws_cfg_get_all(int config_id);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *config_id* | 输入 | int | 要查询的配置ID;0~(最大并发数-1);默认值:0 |
- **返回值说明**
非NULL:指向包含所有Web配置信息的 *qcm_web_config_t* 数组的指针
*NULL*:未找到配置
```{note}
获取的是原始配置信息,请勿随意修改。
```
### qcm_ws_open_proc
- **功能描述**
初始化并打开一个WebSocket连接。
- **函数原型**
```c
qcm_web_err_e qcm_ws_open_proc(qcm_web_open_t *open_t);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *open_t* | 输入 | *qcm_web_open_t** | 指向连接初始化参数结构体的指针,包含建立WebSocket连接所需的配置信息;详见 [*qcm_web_open_t*](#qcmwebopen_t) |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_close_proc
- **功能描述**
关闭指定客户端ID对应的WebSocket连接。
- **函数原型**
```c
qcm_web_err_e qcm_ws_close_proc(int client_id);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 待关闭连接的客户端ID;0~(最大并发数-1);默认值:0 |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_read_proc
- **功能描述**
读取指定客户端的数据到缓冲区。
- **函数原型**
```c
qcm_web_err_e qcm_ws_read_proc(int client_id, char *data, int *size);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 待读取数据的客户端ID;0~(最大并发数-1);默认值:0 |
| *data* | 输出 | char * | 数据缓冲区指针,用于存储读取到的数据 |
| *size* | 输入/输出 | int * | 缓冲区长度指针,传入时为缓冲区最大长度,传出时为实际读取的数据长度 |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_write_proc
- **功能描述**
写入数据到指定的WebSocket客户端。
- **函数原型**
```c
qcm_web_err_e qcm_ws_write_proc(int client_id, char *data, int len, qcm_web_opcode_e opcode);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 待写入数据的客户端ID;0~(最大并发数-1);默认值:0 |
| *data* | 输入 | char * | 待发送数据的缓冲区指针 |
| *len* | 输入 | int | 待发送数据的长度 |
| *opcode* | 输入 | *qcm_web_opcode_e* | 数据帧的操作码,指定数据传输的类型;详见 [*qcm_web_opcode_e*](#qcmwebopcode_e) |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_client_get_curr_conn_status
- **功能描述**
获取当前的WebSocket连接状态和客户端状态。
- **函数原型**
```c
int qcm_ws_client_get_curr_conn_status(int client_id, int *socket_state, int *client_state);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 待查询状态的客户端ID;0~(最大并发数-1);默认值:0 |
| *socket_state* | 输出 | int * | WebSocket连接状态的存储指针,用于返回当前WebSocket的连接状态;取值对应 [*qcm_web_conn_status_e*](#qcmwebconnstatuse) 枚举
*0*:IDLE
*1*:CONNECTING
*2*:CONNECTED
*3*:CLOSING |
| *client_state* | 输出 | int * | 客户端状态的存储指针,用于返回当前客户端的运行状态;取值对应 [*unirtos_web_status_e*](#unirtoswebstatus_e) 枚举
*0*:INIT
*1*:NET
*2*:DNS
*3*:TCP_CONNECTING
*4*:TCP_CONNECTED
*5*:TLS_HANDSHAKE
*6*:TLS_HANDSHAKE_OK
*7*:TLS_HANDSHAKE_FAIL
*8*:HTTP_HANDSHAKE
*9*:HTTP_HANDSHAKE_OK
*10*:HTTP_HANDSHAKE_FAIL
*11*:WebSocket
*12*:TCP_CLOSING
*13*:TCP_CLOSED |
- **返回值说明**
*0*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
### qcm_ws_client_get_send_size
- **功能描述**
获取通过TX通道发送至模块的数据总量,以及通过 *send()* 成功发送的数据量
- **函数原型**
```c
qcm_web_err_e qcm_ws_client_get_send_size(int client_id, int *tx_total_size, int *send_size);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 待查询数据发送量的客户端ID;0~(最大并发数-1);默认值:0 |
| *tx_total_size* | 输出 | int * | TX通道发送至模块的总数据量存储指针;单位:字节 |
| *send_size* | 输出 | int * | 成功发送的数据量存储指针;单位:字节 |
- **返回值说明**
*QCM_WEB_ERR_OK*:函数执行成功
其他值(详见 [*qcm_web_err_e*](#qcmweberr_e)):函数执行失败
## 结构体定义
### qcm_web_cb_t
回调函数相关的数据和状态的结构体定义如下:
```c
typedef struct
{
qcm_web_cb_type_e type;
char *data;
int size;
int result;
} qcm_web_cb_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *type* | *qcm_web_cb_type_e* | 回调类型,用于标识不同的回调事件;详见 [*qcm_web_cb_type_e*](#qcmwebcbtypee) |
| *data* | char * | 回调数据指针,用于存储WebSocket数据 |
| *size* | int | 数据大小,表示WebSocket数据的字节长度 |
| *result* | int | 回调结果,用于表示WebSocket操作的成功/失败状态
*0*:操作成功
非0值:详见 [*qcm_web_err_e*](#qcmweberr_e) |
### qcm_web_open_t
WebSocket打开操作相关参数的结构体定义如下:
```c
typedef struct {
int client_id;
int config_id;
} qcm_web_open_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *client_id* | int | 客户端ID,用于唯一标识客户端,0~(最大并发数-1);默认值:0 |
| *config_id* | int | 配置ID,用于指定客户端的配置信息,0~(最大并发数-1);默认值:0 |
### qcm_web_cfg_t
存储配置信息的结构体定义如下:
```c
typedef struct {
char *str_value;
int str_len;
int int_value;
void *ptr_value;
} qcm_web_cfg_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *str_value* | char * | 字符串类型数据,用于存储配置信息的字符串部分 |
| *str_len* | int | 字符串长度,标识 *str_value* 字段的有效字符长度 |
| *int_value* | int | 整型数据,用于存储配置信息的整型部分 |
| *ptr_value* | void * | 指针类型,可存储配置信息中所需的任意类型数据指针(包括 *header_list*、回调函数指针等) |
### qcm_web_conn_t
连接参数的结构体定义如下:
```c
typedef struct {
int pdp_cid;
int sim_cid;
char *url;
int url_len;
int url_ex;
int subprot_en;
char *subprot;
int subprot_len;
int extension_en;
char *extension;
int extension_len;
char *method;
int method_len;
int timeout;
int ssl_ctx_id;
void *ssl_config;
} qcm_web_conn_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *pdp_cid* | int | PDP上下文ID,用于标识移动网络中的一个会话;范围:*QOSA_PDP_CID_MIN*(0或1)~*QOSA_PDP_CID_MAX*;默认值:1 |
| *sim_cid* | int | SIM卡ID,用于标识正在使用的SIM卡;范围:0~(*QOSA_SIMID_NUM*- 1)
例如,若使用双卡产品,则 *QOSA_SIMID_NUM* 为2,此时0表示SIM卡1;1表示SIM卡2。若使用单卡产品,则 *QOSA_SIMID_NUM* 为1,此时0表示SIM卡1。
默认值:0 |
| *url* | char * | 目标URL,指定要连接的服务器地址和路径 |
| *url_len* | int | URL数据长度,单位:字节 |
| *url_ex* | int | URL是否通过"conn/url-ex"配置,对应 [*qcm_web_url_ex_e*](#qcmweburlexe) 枚举 |
| *subprot_en* | int | 子协议启用标志;对应 [*qcm_web_subprot_e*](#qcmwebsubprot_e) 枚举
*1*:启用
*0*:禁用 |
| *subprot* | char * | 启用子协议时指定要使用的子协议名称 |
| *subprot_len* | int | 子协议名称长度,单位:字节 |
| *extension_en* | int | WebSocket扩展启用标志;对应 [*qcm_web_extension_e*](#qcmwebextension_e) 枚举
*1*:启用
*0*:禁用 |
| *extension* | char * | WebSocket扩展内容,连接时指定要使用的WebSocket扩展 |
| *extension_len* | int | 扩展内容长度,单位:字节 |
| *method* | char * | 连接方式(GET/POST) |
| *method_len* | int | 连接方式长度,单位:字节 |
| *timeout* | int | WebSocket连接超时时间;范围:1~255;默认值:60;单位:秒 |
| *ssl_ctx_id* | int | SSL上下文ID,用于指定WSS连接使用的SSL上下文ID,通过 *qcm_ws_cfg_set()* 设置;范围:0~5,默认值:0。 |
| *ssl_config* | void * | SSL配置内容指针 |
### qcm_web_ping_t
Ping保活配置参数的结构体定义如下:
```c
typedef struct {
int interval;
} qcm_web_ping_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *interval* | int | Ping保活间隔时间;范围:10~3600;默认值:60;单位:秒 |
### qcm_web_read_t
WebSocket读配置的结构体定义如下:
```c
typedef struct {
int buffer_sz;
int timeout;
int mode;
qcm_web_recv_cb_t recv_cb;
} qcm_web_read_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *buffer_sz* | int | WebSocket接收缓存大小;范围:4096~16384;默认值:10240;单位:字节 |
| *timeout* | int | 接收数据超时时间;范围:0~60000;默认值:30000;单位:毫秒
*0*:无限等待 |
| *mode* | int | 数据接收模式
*0*:缓冲模式(默认),先缓存接收数据再返回数据长度
*1*:直推模式,数据直接发送 |
| *recv_cb* | *qcm_web_recv_cb_t* | Web数据接收回调函数,用于处理接收的数据;详见 [*qcm_web_recv_cb_t*](#qcmwebrecvcbt) |
#### qcm_web_recv_cb_t
- **函数原型**
```c
typedef int (*qcm_web_recv_cb_t)(int client_id, qcm_web_cb_t *cb_t);
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | int | 触发回调的客户端ID;0~(最大并发数-1);默认值:0 |
| *cb_t* | 输入 | *qcm_web_cb_t** | 指向回调数据结构体的指针,包含回调类型、数据内容及执行结果等信息;详见 [*qcm_web_cb_t*](#qcmwebcb_t) |
- **返回值说明**
返回值类型为整型,由回调函数实现方自行定义
### qcm_web_write_t
WebSocket写操作配置的结构体定义如下:
```c
typedef struct {
int buffer_sz;
int timeout;
int echo;
} qcm_web_write_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *buffer_sz* | int | WebSocket发送缓存大小;范围:4096~16384;默认值:10240;单位:字节 |
| *timeout* | int | 发送数据超时时间;范围:0~60000;默认值:30000;单位:毫秒
*0*:无限等待 |
| *echo* | int | 发送数据回显控制标志;详见 [*qcm_web_echo_e*](#qcmwebecho_e) |
### qcm_web_close_t
配置WebSocket关闭超时时间的结构体定义如下:
```c
typedef struct {
int wait_time;
} qcm_web_close_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *wait_time* | int | 指定WebSocket关闭的超时时间,单位为秒或毫秒等时间单位 |
### qcm_web_header_list_t
网络包头链表的结构体定义如下:
```c
typedef struct {
qosa_q_link_type_t list;
qcm_web_header_data_t data;
} qcm_web_header_list_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *list* | *qosa_q_link_type_t* | 链表节点,用于请求头的链表管理;详见 [*qosa_q_link_type_t*](#qosaqlinktypet) |
| *data* | *qcm_web_header_data_t* | 链表数据,即请求头键值对数据;详见 [*qcm_web_header_data_t*](#qcmwebheaderdatat) |
### qosa_q_link_type_t
链表节点结构体定义如下(*qosa_q_link_type_t* 是struct *qosa_list_head* 的typedef别名,二者为同一结构体):
```c
typedef struct qosa_list_head qosa_q_link_type_t;
struct qosa_list_head
{
struct qosa_list_head *next;
struct qosa_list_head *prev;
};
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *next* | struct qosa_list_head * | 指向下一个节点 |
| *prev* | struct qosa_list_head * | 指向上一个节点 |
### qcm_web_header_data_t
链表数据结构体定义如下:
```c
typedef struct {
char *key;
char *value;
int key_len;
int value_len;
} qcm_web_header_data_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *key* | char * | 字段名,即数据的键 |
| *value* | char * | 字段内容,即请求头值字符串指针 |
| *key_len* | int | 字段名长度 |
| *value_len* | int | 字段内容长度 |
### qcm_web_config_t
Web服务配置参数结构体定义如下:
```c
typedef struct {
qcm_web_conn_t conn;
qcm_web_ping_t ping;
qcm_web_read_t read;
qcm_web_write_t write;
qcm_web_close_t close;
qosa_q_type_t header_list;
} qcm_web_config_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *conn* | *qcm_web_conn_t* | 网络连接相关配置;详见 [*qcm_web_conn_t*](#qcmwebconn_t) |
| *ping* | *qcm_web_ping_t* | Ping请求相关配置;详见 [*qcm_web_ping_t*](#qcmwebping_t) |
| *read* | *qcm_web_read_t* | 网络连接读数据相关配置;详见 [*qcm_web_read_t*](#qcmwebread_t) |
| *write* | *qcm_web_write_t* | 网络连接写数据相关配置;详见 [*qcm_web_write_t*](#qcmwebwrite_t) |
| *close* | *qcm_web_close_t* | 关闭连接相关配置;详见 [*qcm_web_close_t*](#qcmwebclose_t) |
| *header_list* | *qosa_q_type_t* | 请求头队列;详见 [*qosa_q_type_t*](#qosaqtype_t) |
### qosa_q_type_t
请求头队列结构体定义如下:
```c
typedef struct list_queue_s
{
qosa_uint32_t magic;
struct qosa_list_head head;
qosa_int32_t cnt;
qosa_mutex_t mutex;
} qosa_q_type_t;
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *magic* | qosa_uint32_t | 用于校验队列是否已正确初始化 |
| *head* | struct qosa_list_head | 队列项链表的头节点 |
| *cnt* | qosa_int32_t | 跟踪进入队列的项目数量 |
| *mutex* | *qosa_mutex_t* | 互斥锁,保证队列操作的线程安全;详见 [*qosa_mutex_t*](#qosamutext) |
### qosa_mutex_t
互斥锁不透明指针类型定义如下:
```c
typedef void* qosa_mutex_t;
```
## 枚举定义
### qcm_web_err_e
WebSocket操作错误码枚举定义如下:
```c
typedef enum {
QCM_WEB_ERR_OK = 0,
QCM_WEB_ERROR_UNKNOW = 1,
QCM_WEB_ERR_UNSUPPORTED_PROTOCOL = 2,
QCM_WEB_ERR_INVAL_PARM = 3,
QCM_WEB_ERR_NOMEM = 4,
QCM_WEB_ERR_TIMEDOUT = 5,
QCM_WEB_ERR_BUSY = 6,
QCM_WEB_ERR_NOT_INIT = 7,
QCM_WEB_ERR_NET_FAIL = 8,
QCM_WEB_ERR_ID_OCCUPIED = 9,
QCM_WEB_ERR_INVALID_URL_FORMAT = 10,
QCM_WEB_ERR_INVALID_PORT = 11,
QCM_WEB_ERR_TASK_CREATE = 12,
QCM_WEB_ERR_NET_CLOSE = 13,
QCM_WEB_ERR_NET_DOWN = 14,
QCM_WEB_ERR_WRITE_ = 15,
QCM_WEB_ERR_DNS_FAIL = 16,
QCM_WEB_ERR_TCP_CONNECT_FAIL = 17,
QCM_WEB_ERR_TLS_HANDSHAKE_FAIL = 18,
QCM_WEB_ERR_HTTP_UPGRADE_FAIL = 19,
QCM_WEB_ERR_SEND_BUFF_FULL = 20,
QCM_WEB_ERR_OPERATION_PENDING = 21,
} qcm_web_err_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_ERR_OK* | 操作成功 |
| *QCM_WEB_ERROR_UNKNOW* | 未知错误 |
| *QCM_WEB_ERR_UNSUPPORTED_PROTOCOL* | 不支持的协议 |
| *QCM_WEB_ERR_INVAL_PARM* | 无效参数 |
| *QCM_WEB_ERR_NOMEM* | 内存不足 |
| *QCM_WEB_ERR_TIMEDOUT* | 超时错误 |
| *QCM_WEB_ERR_BUSY* | 忙碌错误 |
| *QCM_WEB_ERR_NOT_INIT* | 未初始化错误 |
| *QCM_WEB_ERR_NET_FAIL* | 网络错误 |
| *QCM_WEB_ERR_ID_OCCUPIED* | ID已占用错误 |
| *QCM_WEB_ERR_INVALID_URL_FORMAT* | 无效URL错误 |
| *QCM_WEB_ERR_INVALID_PORT* | 无效端口错误 |
| *QCM_WEB_ERR_TASK_CREATE* | 任务创建失败错误 |
| *QCM_WEB_ERR_NET_CLOSE* | 网络连接已关闭错误 |
| *QCM_WEB_ERR_NET_DOWN* | 网络故障错误 |
| *QCM_WEB_ERR_WRITE_* | 内存不足错误 |
| *QCM_WEB_ERR_DNS_FAIL* | DNS解析失败错误 |
| *QCM_WEB_ERR_TCP_CONNECT_FAIL* | TCP连接失败错误 |
| *QCM_WEB_ERR_TLS_HANDSHAKE_FAIL* | TLS握手失败错误 |
| *QCM_WEB_ERR_HTTP_UPGRADE_FAIL* | HTTP升级失败错误 |
| *QCM_WEB_ERR_SEND_BUFF_FULL* | 发送缓冲区已满错误 |
| *QCM_WEB_ERR_OPERATION_PENDING* | 操作未完成错误 |
### unirtos_web_status_e
WebSocket连接状态枚举定义如下:
```c
typedef enum
{
QCM_WEB_STATUS_INIT = 0,
QCM_WEB_STATUS_NET,
QCM_WEB_STATUS_DNS,
QCM_WEB_STATUS_TCP_CONNECTING,
QCM_WEB_STATUS_TCP_CONNECTED,
QCM_WEB_STATUS_TLS_HANDSHAKE = 5,
QCM_WEB_STATUS_TLS_HANDSHAKE_OK,
QCM_WEB_STATUS_TLS_HANDSHAKE_FAIL,
QCM_WEB_STATUS_HTTP_HANDSHAKE,
QCM_WEB_STATUS_HTTP_HANDSHAKE_OK,
QCM_WEB_STATUS_HTTP_HANDSHAKE_FAIL = 10,
QCM_WEB_STATUS_WebSocket,
QCM_WEB_STATUS_TCP_CLOSING,
QCM_WEB_STATUS_TCP_CLOSED,
} unirtos_web_status_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_STATUS_INIT* | 初始化状态 |
| *QCM_WEB_STATUS_NET* | 网络可用 |
| *QCM_WEB_STATUS_DNS* | DNS解析中 |
| *QCM_WEB_STATUS_TCP_CONNECTING* | TCP连接中 |
| *QCM_WEB_STATUS_TCP_CONNECTED* | TCP已连接 |
| *QCM_WEB_STATUS_TLS_HANDSHAKE* | TLS握手中 |
| *QCM_WEB_STATUS_TLS_HANDSHAKE_OK* | TLS握手成功 |
| *QCM_WEB_STATUS_TLS_HANDSHAKE_FAIL* | TLS握手失败 |
| *QCM_WEB_STATUS_HTTP_HANDSHAKE* | HTTP握手中 |
| *QCM_WEB_STATUS_HTTP_HANDSHAKE_OK* | HTTP握手成功 |
| *QCM_WEB_STATUS_HTTP_HANDSHAKE_FAIL* | HTTP握手失败 |
| *QCM_WEB_STATUS_WebSocket* | WebSocket已连接 |
| *QCM_WEB_STATUS_TCP_CLOSING* | 正在关闭连接 |
| *QCM_WEB_STATUS_TCP_CLOSED* | 连接已关闭 |
### qcm_web_cfg_e
Web配置参数枚举定义如下:
```c
typedef enum {
QCM_WEB_CFG_CONN_PDPCID = 0,
QCM_WEB_CFG_CONN_SIMCID,
QCM_WEB_CFG_CONN_SSL_CTX_ID,
QCM_WEB_CFG_CONN_SSLCONFIG,
QCM_WEB_CFG_CONN_URL,
QCM_WEB_CFG_CONN_URL_EX,
QCM_WEB_CFG_CONN_SUBPROT_EN,
QCM_WEB_CFG_CONN_SUBPROT,
QCM_WEB_CFG_CONN_EXTENSION_EN,
QCM_WEB_CFG_CONN_EXTENSION,
QCM_WEB_CFG_CONN_METHOD,
QCM_WEB_CFG_CONN_TIMEOUT,
QCM_WEB_CFG_PING_INTERVAL,
QCM_WEB_CFG_WRITE_BUFFERSZ,
QCM_WEB_CFG_WRITE_TIMEOUT,
QCM_WEB_CFG_WRITE_ECHO,
QCM_WEB_CFG_READ_BUFFERSZ,
QCM_WEB_CFG_READ_TIMEOUT,
QCM_WEB_CFG_READ_MODE,
QCM_WEB_CFG_CLOSE_WAITTIME,
QCM_WEB_CFG_RECV_CB,
QCM_WEB_CFG_REQHEAD,
QCM_WEB_CFG_REQHEAD_DEL,
QCM_WEB_CFG_REQHEAD_DEL_ALL,
QCM_WEB_CFG_MAX,
} qcm_web_cfg_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_CFG_CONN_PDPCID* | 连接的PDP上下文ID |
| *QCM_WEB_CFG_CONN_SIMCID* | 连接的SIM卡ID |
| *QCM_WEB_CFG_CONN_SSL_CTX_ID* | SSL上下文ID |
| *QCM_WEB_CFG_CONN_SSLCONFIG* | SSL配置 |
| *QCM_WEB_CFG_CONN_URL* | 连接的URL |
| *QCM_WEB_CFG_CONN_URL_EX* | URL是否通过"conn/url-ex"命令配置 |
| *QCM_WEB_CFG_CONN_SUBPROT_EN* | 子协议启用标志 |
| *QCM_WEB_CFG_CONN_SUBPROT* | 子协议 |
| *QCM_WEB_CFG_CONN_EXTENSION_EN* | 扩展功能启用标志 |
| *QCM_WEB_CFG_CONN_EXTENSION* | 扩展功能 |
| *QCM_WEB_CFG_CONN_METHOD* | 连接方式 |
| *QCM_WEB_CFG_CONN_TIMEOUT* | 连接超时时间 |
| *QCM_WEB_CFG_PING_INTERVAL* | Ping间隔时间 |
| *QCM_WEB_CFG_WRITE_BUFFERSZ* | 写缓冲区大小 |
| *QCM_WEB_CFG_WRITE_TIMEOUT* | 写操作超时时间 |
| *QCM_WEB_CFG_WRITE_ECHO* | 写操作回显 |
| *QCM_WEB_CFG_READ_BUFFERSZ* | 读缓冲区大小 |
| *QCM_WEB_CFG_READ_TIMEOUT* | 读操作超时时间 |
| *QCM_WEB_CFG_READ_MODE* | 读操作模式 |
| *QCM_WEB_CFG_CLOSE_WAITTIME* | 关闭等待时间 |
| *QCM_WEB_CFG_RECV_CB* | 接收回调函数 |
| *QCM_WEB_CFG_REQHEAD* | 添加自定义请求头 |
| *QCM_WEB_CFG_REQHEAD_DEL* | 删除自定义请求头 |
| *QCM_WEB_CFG_REQHEAD_DEL_ALL* | 删除所有自定义请求头 |
| *QCM_WEB_CFG_MAX* | 枚举最大值 |
### qcm_web_echo_e
数据回显模式枚举定义如下:
```c
typedef enum {
QCM_WEB_ECHO_OFF = 0,
QCM_WEB_ECHO_ON = 1,
} qcm_web_echo_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_ECHO_OFF* | 禁用回显模式(默认) |
| *QCM_WEB_ECHO_ON* | 启用回显模式 |
### qcm_web_mode_e
数据上报模式枚举定义如下:
```c
typedef enum {
QCM_WEB_MODE_BUFFER = 0,
QCM_WEB_MODE_PUSH = 1,
} qcm_web_mode_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_MODE_BUFFER* | 缓冲模式:数据先缓存再处理 |
| *QCM_WEB_MODE_PUSH* | 直推模式:数据直接发送,不缓存 |
### qcm_web_url_ex_e
WebSocket URL扩展配置使能状态枚举定义如下:
```c
typedef enum {
QCM_WEB_URL_EX_DISABLE = 0,
QCM_WEB_URL_EX_ENABLE = 1,
} qcm_web_url_ex_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_URL_EX_DISABLE* | URL未通过"conn/url-ex"配置 |
| *QCM_WEB_URL_EX_ENABLE* | URL通过"conn/url-ex"配置 |
### qcm_web_subprot_e
WebSocket子协议启用状态枚举定义如下:
```c
typedef enum {
QCM_WEB_SUBPROT_DISABLE = 0,
QCM_WEB_SUBPROT_ENABLE = 1,
} qcm_web_subprot_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_SUBPROT_DISABLE* | WebSocket子协议已禁用 |
| *QCM_WEB_SUBPROT_ENABLE* | WebSocket子协议已启用 |
### qcm_web_extension_e
WebSocket扩展协议启用状态枚举定义如下:
```c
typedef enum {
QCM_WEB_EXTENSION_DISABLE = 0,
QCM_WEB_EXTENSION_ENABLE = 1,
} qcm_web_extension_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_EXTENSION_DISABLE* | WebSocket自定义扩展已禁用 |
| *QCM_WEB_EXTENSION_ENABLE* | WebSocket自定义扩展已启用 |
### qcm_web_opcode_e
数据帧操作码枚举定义如下:
```c
typedef enum {
QCM_WEB_OPCODE_TEXT = 0,
QCM_WEB_OPCODE_BINARY = 1,
} qcm_web_opcode_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_OPCODE_TEXT* | 文本帧 |
| *QCM_WEB_OPCODE_BINARY* | 二进制帧 |
### qcm_web_cb_type_e
WebSocket回调事件类型枚举定义如下:
```c
typedef enum {
QCM_WEB_TYPE_OPEN = 0,
QCM_WEB_TYPE_RECV,
QCM_WEB_TYPE_CLOSE,
QCM_WEB_TYPE_WRITE,
} qcm_web_cb_type_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_TYPE_OPEN* | 打开网络连接 |
| *QCM_WEB_TYPE_RECV* | 接收网络数据 |
| *QCM_WEB_TYPE_CLOSE* | 关闭网络连接 |
| *QCM_WEB_TYPE_WRITE* | 可继续发送网络数据 |
### qcm_web_conn_status_e
WebSocket套接字连接状态枚举定义如下:
```c
typedef enum {
QCM_WEB_CONN_STA_IDLE = 0,
QCM_WEB_CONN_STA_CONNECTING,
QCM_WEB_CONN_STA_CONNECTED,
QCM_WEB_CONN_STA_CLOSING,
QCM_WEB_CONN_STA_CLOSED = QCM_WEB_CONN_STA_IDLE,
} qcm_web_conn_status_e;
```
| **成员** | **说明** |
| --- | --- |
| *QCM_WEB_CONN_STA_IDLE* | 客户端连接尚未建立或已关闭并销毁 |
| *QCM_WEB_CONN_STA_CONNECTING* | 客户端正在连接 |
| *QCM_WEB_CONN_STA_CONNECTED* | 客户端连接已建立 |
| *QCM_WEB_CONN_STA_CLOSING* | 客户端连接正在断开 |
| *QCM_WEB_CONN_STA_CLOSED* | 客户端连接尚未建立或已关闭并销毁(同 *QCM_WEB_CONN_STA_IDLE*) |
# 应用逻辑流程图
```{image} images/board_PwwewvdAJhlqq5bXfmQcS1XLn2d.jpg
:width: 903px
:height: 1082px
:align: center
```
# 示例代码
完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/network_protocol/WebSocket/WebSocket_demo.c