【C++】libwebsockets 服务端示例

前言

Libwebsockets is a simple-to-use, MIT-license, pure C library providing client and server for http/1, http/2, websockets, MQTT and other protocols in a security-minded, lightweight, configurable, scalable and flexible way. It’s easy to build and cross-build via cmake and is suitable for tasks from embedded RTOS through mass cloud serving.

libwebsockets 是一个简单易用的、MIT 许可的、纯 C 语言库,提供了 HTTP/1、HTTP/2、WebSockets、MQTT 和其他协议的客户端和服务器实现。它以安全为导向,轻量级、可配置、可扩展和灵活。通过 cmake 构建和交叉构建非常容易,适用于从嵌入式 RTOS 到大规模云服务的任务。

留作备忘。

正文

代码仓库

代码示例

cpp
#include <libwebsockets.h>
#include <signal.h>
#include <string.h>

static int exit_sig = 0;
#define MAX_PAYLOAD_SIZE 10 * 1024

void dosomething()
{
    printf("dosomething\n");
}

void sighdl(int sig)
{
    lwsl_notice("%d traped", sig);
    exit_sig = 1;
}

/**
 * 会话上下文对象,结构根据需要自定义
 */
struct session_data
{
    int msg_count;
    unsigned char buf[LWS_PRE + MAX_PAYLOAD_SIZE];
    int len;
    bool bin;
    bool fin;
};

static int protocol_my_callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
    struct session_data *data = (struct session_data *)user;
    switch (reason)
    {
    case LWS_CALLBACK_ESTABLISHED:
        lwsl_debug("Client connect!\n");
        data->len = 0;
        break;

    case LWS_CALLBACK_RECEIVE:
        lwsl_debug("LWS_CALLBACK_RECEIVE\n");
        data->fin = lws_is_final_fragment(wsi);
        data->bin = lws_frame_is_binary(wsi);
        lws_rx_flow_control(wsi, 0);

        memcpy(&data->buf[LWS_PRE + data->len], in, len);
        data->len += len;

        if (data->fin)
        {
            dosomething();
            lwsl_debug("Received: %s\n", &data->buf[LWS_PRE]);
            lws_callback_on_writable(wsi);
        }
        break;
    case LWS_CALLBACK_SERVER_WRITEABLE:
        lws_write(wsi, &data->buf[LWS_PRE], data->len, LWS_WRITE_TEXT);
        data->len = 0;
        memset(data->buf, 0, sizeof(data->buf));
        lws_rx_flow_control(wsi, 1);
        break;
    }
    return 0;
}

/**
 * 支持的WebSocket子协议数组
 * 子协议即JavaScript客户端WebSocket(url, protocols)第2参数数组的元素
 * 你需要为每种协议提供回调函数
 */
struct lws_protocols protocols[] = {
    {
        // 协议名称,协议回调,接收缓冲区大小
        "ws",
        protocol_my_callback,
        sizeof(struct session_data),
        MAX_PAYLOAD_SIZE,
    },
    {
        NULL, NULL, 0 // 最后一个元素固定为此格式
    }};

int main(int argc, char **argv)
{
    signal(SIGTERM, sighdl);

    struct lws_context_creation_info ctx_info = {0};
    ctx_info.port = 8000;
    // ctx_info.iface = NULL; // 在所有网络接口上监听
    ctx_info.protocols = protocols;
    ctx_info.gid = -1;
    ctx_info.uid = -1;
    ctx_info.options = LWS_SERVER_OPTION_VALIDATE_UTF8;

    // ctx_info.ssl_ca_filepath = "../ca/ca-cert.pem";
    // ctx_info.ssl_cert_filepath = "./server-cert.pem";
    // ctx_info.ssl_private_key_filepath = "./server-key.pem";
    // ctx_info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
    // ctx_info.options |= LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;

    struct lws_context *context = lws_create_context(&ctx_info);
    while (!exit_sig)
    {
        lws_service(context, 1000);
    }
    lws_context_destroy(context);

    return 0;
}

最后

End!

【C++】std::sort 原理
【RK3588】关于 devfreq 和 cpufreq 的记录