跳转至

CoAP

CoAP(Constrained Application Protocol)、UDP Socket

前置阅读:TCP/UDP

学习目标

  • 理解 CoAP 的设计理念——为资源受限设备设计的 RESTful 协议,基于 UDP
  • 掌握 CoAP GET/PUT/POST/DELETE 与 HTTP 的对应关系
  • 掌握 CoAP 可观察(Observe)模式——Server 数据变化时主动通知 Client
  • 能够在 WS63 上实现 CoAP 服务端或客户端

基本概念

CoAP vs MQTT

对比项 CoAP MQTT
传输层 UDP(无连接、更轻量) TCP(可靠有序)
模型 RESTful(URI 资源) 发布/订阅(Topic)
需要 Broker 不需要(直连) 需要
安全 DTLS TLS
适用场景 局域网低功耗设备 跨互联网云平台

RESTful 模型

CoAP URI 标识资源,方法操作资源:

方法 对应 HTTP 说明
GET GET 读取资源值
PUT PUT 更新资源值
POST POST 创建新资源
DELETE DELETE 删除资源

可观察(Observe)模式

Client 注册对某资源的观察 → Server 资源值变化时自动推送——类似 MQTT Subscribe 但无需 Broker。

涉及 API

API 用途
CoAP context 初始化 创建 CoAP context
coap_add_resource() Server 注册资源 URI
coap_register_observe() Server 注册可观察资源
coap_send_request() Client 发送 GET/PUT/POST
CoAP 响应回调 Client 收到 Server 回复

CoAP 通常通过第三方库(如 libcoap)实现,具体 API 以 SDK 实际集成为准。

案例说明

做什么

WS63 作为 CoAP Server 暴露温度资源 → CoAP Client 通过 GET 读取 → 注册 Observe 接收温度变化推送。

关键配置

参数 推荐值 说明
CoAP 端口 5683 标准端口(5684 = DTLS 加密)
Observe 推送间隔 温度变化 > 0.5°C 避免频繁推送
消息可靠性 CON / NON CON 需 ACK 确认、NON 不需

代码详解

CoAP Server 注册资源

/* 温度资源 GET handler */
static void temp_get_handler(coap_context_t *ctx,
                              coap_resource_t *resource,
                              coap_session_t *session,
                              coap_pdu_t *request,
                              coap_binary_t *token,
                              coap_string_t *query,
                              coap_pdu_t *response) {
    float temp = read_temperature();
    coap_add_data(response, sizeof(temp), (uint8_t *)&temp);
}

/* 注册资源 */
coap_resource_t *res = coap_resource_init(
    coap_make_str_const("/sensors/temp"),
    COAP_RESOURCE_FLAGS_NOTIFYABLE);
coap_resource_set_get_observable(res, 1);
coap_register_handler(res, COAP_REQUEST_GET, temp_get_handler);
coap_add_resource(ctx, res);

Observe 推送

/* 温度变化时通知所有 Observer */
void notify_temp_change(coap_context_t *ctx, float new_temp) {
    coap_resource_notify_observers(
        ctx->resource,              // "/sensors/temp" 资源
        NULL, NULL,                 // 通知所有观察者
        sizeof(new_temp),
        (uint8_t *)&new_temp);
}

Client GET 请求

coap_pdu_t *pdu = coap_new_pdu(COAP_MESSAGE_CON, COAP_REQUEST_GET);
coap_add_option(pdu, COAP_OPTION_URI_PATH,
                coap_make_str_const("sensors/temp"));
coap_send(session, pdu);
/* 等待 Server 响应——包含温度值 */