libwebsockets常用接口及客户端基本流程

1. 常用接口

由于项目的需要,要使用libwebsockets实现客户端固件与服务端的通讯,因此整理了libwebsockets的一些常用接口

接口名称接口说明函数原型
lws_create_context创建 WebSocket 上下文,初始化网络环境并配置上下文。struct lws_context *lws_create_context(const struct lws_context_creation_info *info);
lws_context_destroy销毁 WebSocket 上下文,释放资源并关闭网络连接。void lws_context_destroy(struct lws_context *context);
lws_service处理 WebSocket 事件,包括接收和发送数据、连接状态变化等。int lws_service(struct lws_context *context, int timeout_ms);
lws_client_connect_via_info通过给定的连接信息建立 WebSocket 客户端连接。int lws_client_connect_via_info(struct lws_client_connect_info *info);
lws_callback_on_writable将指定的套接字注册到可写事件的回调函数中,用于异步发送数据。int lws_callback_on_writable(struct lws *wsi);
lws_callback_on_writable_all将所有套接字注册到可写事件的回调函数中,用于批量异步发送数据。int lws_callback_on_writable_all(struct lws_context *context);
lws_write向指定的套接字发送数据。int lws_write(struct lws *wsi, unsigned char *buf, size_t len, enum lws_write_protocol protocol);
lws_rx_flow_control控制接收数据的流量。int lws_rx_flow_control(struct lws *wsi, int enable);
lws_get_peer_simple获取远程对等端的信息。int lws_get_peer_simple(struct lws *wsi, char *name, size_t name_capacity);
lws_get_peer_simple获取远程对等端的信息。int lws_get_peer_simple(struct lws *wsi, char *name, size_t name_capacity);
lws_set_log_level设置日志级别,控制日志的输出。void lws_set_log_level(int level, void (*log_function)(int level, const char *line));
lws_state_notification_add添加状态变化通知器,用于接收系统状态的变化通知。int lws_state_notification_add(struct lws_context *context, struct lws_state_notify_link *notify);
lws_state_notification_remove移除状态变化通知器。int lws_state_notification_remove(struct lws_state_notify_link *notify);
lws_create_vhost创建虚拟主机,用于支持多个不同的域名和协议。struct lws_vhost *lws_create_vhost(struct lws_context *context, const struct lws_context_creation_info *info);
lws_vhost_destroy销毁虚拟主机。void lws_vhost_destroy(struct lws_vhost *vhost);

2. 客户端的基本流程

作为客户端,使用 libwebsockets 与服务器进行通信的基本流程通常如下:

1. **创建 WebSocket 上下文**:首先,需要创建一个 WebSocket 上下文,用于管理客户端与服务器之间的连接和通信。可以使用 `lws_create_context` 函数创建 WebSocket 上下文,并配置相应的参数。

2. **建立连接**:使用 `struct lws_client_connect_info` 结构设置要连接的服务器的相关信息,包括服务器地址、端口号、协议等。然后,使用 `lws_client_connect_via_info` 函数向服务器发起连接请求。

3. **事件循环**:进入事件循环,不断调用 `lws_service` 函数处理 WebSocket 事件,包括接收和发送数据、连接状态变化等。在事件循环中,可以处理服务器发送的数据,并根据需要向服务器发送数据。

4. **发送和接收数据**:在事件循环中,可以调用 `lws_write` 函数向服务器发送数据,并通过注册相应的回调函数来处理服务器发送的数据。通常,客户端通过注册 `LWS_CALLBACK_CLIENT_RECEIVE` 回调函数来处理服务器发送的数据。

5. **关闭连接**:当通信完成或需要关闭连接时,可以调用 `lws_context_destroy` 函数销毁 WebSocket 上下文,关闭与服务器的连接,并释放相关资源。

下面是一个简单的示例,演示了基本的客户端与服务器通信流程:

```c
#include <libwebsockets.h>

int main() {
    struct lws_context_creation_info info;
    struct lws_context *context;
    struct lws *wsi;
    const char *server_url = "ws://example.com:8080";

    // 创建 WebSocket 上下文
    memset(&info, 0, sizeof(info));
    // 设置info中的相关参数
    context = lws_create_context(&info);
    if (!context) {
        lwsl_err("Failed to create WebSocket context\n");
        return -1;
    }

    // 设置连接信息
    struct lws_client_connect_info connect_info;
    memset(&connect_info, 0, sizeof(connect_info));
    connect_info.context = context;
    connect_info.address = server_url;
    connect_info.port = 80;
    connect_info.path = "/";
    connect_info.host = "example.com";
    connect_info.origin = "http://example.com";
    connect_info.protocol = "example-protocol";

    // 发起连接
    wsi = lws_client_connect_via_info(&connect_info);
    if (!wsi) {
        lwsl_err("Failed to connect to server\n");
        lws_context_destroy(context);
        return -1;
    }

    // 进入事件循环
    while (1) {
        lws_service(context, 0);
        // 在此处理收发数据等操作
    }

    // 销毁 WebSocket 上下文
    lws_context_destroy(context);

    return 0;
}
```

在实际应用中,可能需要根据具体的需求和场景对以上流程进行适当调整和扩展。

### 如何使用 `libwebsockets` 编写客户端 #### 客户端初始化与配置 为了创建基于 `libwebsockets` 的 WebSocket 客户端应用程序,首先需要引入必要的头文件并定义上下文结构体来保存连接信息。这通常涉及设置日志级别、协议列表以及其他选项。 ```c #include <libwebsockets.h> struct lws_context_creation_info info; memset(&info, 0, sizeof(info)); info.port = CONTEXT_PORT_NO_LISTEN; /* 不监听任何端口 */ info.protocols = protocols; /* 协议数组 */ info.gid = -1; info.uid = -1; /* 创建上下文实例 */ lws_context *context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "创建上下文失败\n"); return -1; } ``` #### 建立到服务器的连接 通过调用 `lws_client_connect_via_info()` 函数可以建立至目标WebSocket服务端的链接。在此之前需先填充好描述目的地址和服务详情的信息结构体。 ```c struct lws_client_connect_info i; memset(&i, 0, sizeof(i)); i.context = context; i.address = "example.com"; // 远程主机名或IP地址 i.port = 80; // 端口号,默认HTTP为80 i.path = "/demo"; // URL路径部分 i.host = i.address; // HTTP/1.1 Host: header value i.origin = "http://localhost"; // Origin: header value i.protocol = protocols[0].name; // 使用的第一个协议名称 i.ssl_connection = LCCSCF_USE_SSL // 是否启用SSL/TLS加密通信 // 执行实际连接操作 lws *wsi = lws_client_connect_via_info(&i); if (!wsi){ printf("无法连接到 %s:%d\n", i.address, i.port); } else { printf("成功连接到 %s:%d\n", i.address, i.port); } ``` #### 处理消息回调函数 当接收到数据帧时会触发相应的事件处理程序,在此期间可对接收的数据做进一步解析和响应逻辑实现。下面是一个简单的接收文本消息的例子: ```c static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { switch(reason) { case LWS_CALLBACK_CLIENT_RECEIVE: printf("Received message from server:\n%s\n", (char *)in); break; default: break; } return lws_callback_http_dummy(wsi, reason, user, in, len); } const struct lws_protocols protocols[] = { { "http-only", callback_http }, { NULL, NULL } /* terminator */ }; ``` 以上展示了利用 C 库 `libwebsockets` 构建基本 WebSocket 客户端所需的关键组件[^1]。对于更复杂的应用场景,则可能还需要考虑错误恢复机制、并发控制等方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值