早些年还在使用2.4+版本,现在最新版已经到4.1+,centos 7也使用3.+版本。对于使用外部eventloop相关的接口发生了大的变更。libev也应为早早对iouring支持,4+版本亲睐libev而不在是libuv。

首先是接口

libwebsockets一直以来都支持libuv,libev以及libevent。

在2.4+时候,通过接口函数lws_uv_initloop, lws_ev_initloop以及lws_event_initloop指定使用外部eventloop。

在3.0.0开始,这三个函数被去掉,取而代之是在lws_context_creation_info结构添加一个新成员foreign_loops,并为options成员添加三个新选项LWS_SERVER_OPTION_LIBUV, LWS_SERVER_OPTION_LIBEV以及LWS_SERVER_OPTION_LIBEVENT, 在lws_create_context时加载plugin的方式。

可以参看下面地址:https://libwebsockets.org/abi/headers_diff/libwebsockets/2.4.2/3.0.0/diff.html

编译时,可以选择动态或静态两种plugin方式,yum释放的libwebsockets使用3.0.1并且只支持libuv的静态plugin。 对于使用自己编译的libwebsockets.so动态加载evlib_plugin失败的情况,因为代码默认只搜索安装路径,如果有需要的话,可以修改lib/core/context.c的dlist,添加"."等相对路径。

另外libev好像要变强了?4+后的libwebsockets不再偏向libuv而转向libev。你会发现,4+的libwebsockets在CMake时候多了两个检查,分别是LWS_HAVE_EVBACKEND_LINUXAIO跟LWS_HAVE_EVBACKEND_IOURING,重点是iouring,linux5的东东。libev已经支持了。

iouring可以参考: https://kkc.github.io/2020/08/19/io-uring/

题目结束。

==========

libwebsockets使用注意

1。对方的ping,本方pong后会触发一次PULLOUT,LWS_CALLBACK_CLIENT_WRITEABLE。

2。lws_parse_uri函数设计有问题。第一输入参数uri,分析后prot,address,path三个输出参数以const char*指针指向uri字符串对应子字符串的位置,意思是不可以修改输出的子字符串,但是自己有对输入参数uri进行了修改,替换'\0'。所以不能用全局只读区的字符串,还有你的配置字符串或留底的字符串。path有一个缺陷,你要在前面加'/',你又要新建一个字符串。这里可以考虑在拷贝uri多留空间,在path的位置movemem后加'/'。

3。LWS_CALLBACK_WSI_CREATE与描述不同,client端通知对应的协议。而server端因为在ws握手之前不清楚protocol,所以分派到protocol[0]。LWS_CALLBACK_CLIENT_CONNECTION_ERROR,同理。

LWS_CALLBACK_WSI_DESTROY分派到protocol[0]。

LWS_CALLBACK_WSI_CREATE                    = 29,
/**< outermost (earliest) wsi create notification to protocols[0] */ LWS_CALLBACK_WSI_DESTROY = 30,
/**< outermost (latest) wsi destroy notification to protocols[0] */

4。client流程事件:

a。socket connect成功后,LWS_CALLBACK_WSI_CREATE,参考3。

b。ssl握手,ws握手,收到101成功后,LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP,

b1。lws_role_transition结束,lws确认ws握手成功,LWS_CALLBACK_CLIENT_ESTABLISHED。

c。如果b。失败,LWS_CALLBACK_CLIENT_CONNECTION_ERROR,参考3。跳到e。

d。ws断开,LWS_CALLBACK_CLIENT_CLOSED。

e。LWS_CALLBACK_WSI_DESTROY。

在LWS_CALLBACK_CLIENT_CLOSED清理user。只在LWS_CALLBACK_CLIENT_ESTABLISHED时,才使用user的内存构建内容。

5。四种私有对象:

a。lws_protocol.user,由用户管理资源,生命周期不短于lws_context。

b。callback的user参数,由eventloop管理资源,生命周期不长于lws。

c。lws_vhost的priv。资源应在eventloop里进行管理,生命周期不长于protocol。

d。lws_vhost的user,由用户管理资源,生命周期不短于lws_context。

==========

libevent-2.2使用注意

1。bufferevent_openssl_socket_new with BEV_OPT_CLOSE_ON_FREE,不论成功与否,ssl都被接管,不能手动SSL_free。

2。evhttp_connection_base_bufferevent_new,只有成功了bev才会被接管,如果失败了还得手动进行bufferevent_free。

3。evhttp_make_request函数后evhttp_request_free会被接管,你就不要再去访问evhttp_request了,除了eventloop里面的callback。但是失败是好像有一种例外的情况,39行只TAILQ_REMOVE并没有evhttp_request_free_auto,对比12行返回-1前evhttp_request_free_auto。而evhttp_connection_fail_只对requests链首进行evhttp_request_free_(TAILQ_REMOVE+evhttp_request_free_auto),如果当前req不是链首,就只TAILQ_REMOVE,谁管?如果当前req是链首,已经被evhttp_connection_fail_处理掉了,还怎么能访问并TAILQ_REMOVE?

 1 evhttp_make_request(struct evhttp_connection *evcon,
2 struct evhttp_request *req,
3 enum evhttp_cmd_type type, const char *uri)
4 {
5 /* We are making a request */
6 req->kind = EVHTTP_REQUEST;
7 req->type = type;
8 if (req->uri != NULL)
9 mm_free(req->uri);
10 if ((req->uri = mm_strdup(uri)) == NULL) {
11 event_warn("%s: strdup", __func__);
12 evhttp_request_free_auto(req);
13 return (-1);
14 }
15
16 /* Set the protocol version if it is not supplied */
17 if (!req->major && !req->minor) {
18 req->major = 1;
19 req->minor = 1;
20 }
21
22 EVUTIL_ASSERT(req->evcon == NULL);
23 req->evcon = evcon;
24 EVUTIL_ASSERT(!(req->flags & EVHTTP_REQ_OWN_CONNECTION));
25
26 TAILQ_INSERT_TAIL(&evcon->requests, req, next);
27
28 /* We do not want to conflict with retry_ev */
29 if (evcon->retry_cnt)
30 return (0);
31
32 /* If the connection object is not connected; make it so */
33 if (!evhttp_connected(evcon)) {
34 int res = evhttp_connection_connect_(evcon);
35 /* evhttp_connection_fail_(), which is called through
36 * evhttp_connection_connect_(), assumes that req lies in
37 * evcon->requests. Thus, enqueue the request in advance and
38 * remove it in the error case. */
39 if (res != 0)
40 TAILQ_REMOVE(&evcon->requests, req, next);
41
42 return (res);
43 }
44
45 /*
46 * If it's connected already and we are the first in the queue,
47 * then we can dispatch this request immediately. Otherwise, it
48 * will be dispatched once the pending requests are completed.
49 */
50 if (TAILQ_FIRST(&evcon->requests) == req)
51 evhttp_request_dispatch(evcon);
52
53 return (0);
54 }

libwebsockets支持外部eventloop变更的更多相关文章

  1. Remix 搭建与简单使用,并支持外部访问

    Remix 搭建与简单使用,并支持外部访问 转 https://blog.csdn.net/linshenyuan1213/article/details/83444911 remix是基于浏览器的在 ...

  2. 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  3. [C# ASP.NET]如何让IIS Express支持外部(局域网)连接

    声明:本文为www.cnc6.cn原创,转载时请注明出处,谢谢! 一.搭建环境: 1.系统:Win10 1809 2.IDE:Visual Studio 2017 3.Framework: 4.6.1 ...

  4. 让IIS Express 也支持外部链接

  5. 如果给IIS添加防火墙入站配置,支持外部或者局域网访问

    背景简介 也许你试着在本机IIS运行了一些网站,但是奇怪的是,同网络的终端却无法访问你,这时候极有可能被防火墙拦截了,所以我们要找到正确的姿势来开启魔法了. 找到入站规则设置 不管你是Win7还是Wi ...

  6. 【转载】Spark SQL之External DataSource外部数据源

    http://blog.csdn.net/oopsoom/article/details/42061077 一.Spark SQL External DataSource简介 随着Spark1.2的发 ...

  7. VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试

    VS2013内置了IISExpress.做asp.net MVC的web项目开发时,Ctrl+F5和F5启动项目运行(后者是调试模式)的同时都会打开IISExpress,事实上本机对该web项目走的就 ...

  8. TiDB:支持 MySQL 协议的分布式数据库解决方案

    [编者按]TiDB 是国内 PingCAP 团队开发的一个分布式 SQL 数据库.其灵感来自于 Google 的 F1,TiDB 支持包括传统 RDBMS 和 NoSQL 的特性.在国内 ITOM 管 ...

  9. 【转并修改】VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试

    转:http://www.cnblogs.com/ShaYeBlog/p/4072074.html VS2013内置了IISExpress.做asp.net MVC的web项目开发时,Ctrl+F5和 ...

  10. C++11 : 外部模板(Extern Template)

    在C++98/03语言标准中,对于源代码中出现的每一处模板实例化,编译器都需要去做实例化的工作:而在链接时,链接器还需要移除重复的实例化代码.显然,让编译器每次都去进行重复的实例化工作显然是不必要的, ...

随机推荐

  1. ARKit的理解与使用

    AR概述 AR的意义:让虚拟世界套与现实世界建立联系,并可以进行互动. AR的技术实现:通过实时地计算摄影机输出影像的位置及角度,并在内部通过算法识别将场景中的事物,然后在内部模拟的三维坐标系中给识别 ...

  2. 开发必备,开源 or 免费的 AI 编程助手

    AI 大模型的火热,让开发圈近来如虎添翼,各种各样基于 AI 技术的开发者工具和新范式不断涌现,尤其是 Github 和 OpenAI 共同推出的 Copilot X ,更是一骑绝尘.本文推荐一些开源 ...

  3. DNS子域委派配置·

    实验介绍:DNS子域委派的作用 子域即为主域下的一个子域名,当一个子域的流量过大时,主域的DNS服务器可以把一个子域的查询授权给一台专门的子域服务器 注意被委派的服务器必须是委派服务器的子域服务器. ...

  4. Kafka的ACK机制

    Kafka的ack机制,指的是producer的消息发送确认机制,这直接影响到Kafka集群的吞吐量和消息可靠性.而吞吐量和可靠性就像硬币的两面,两者不可兼得,只能平衡. ACK有3个可选值,分别是1 ...

  5. CF1916

    重点在 E B 如果 \(lcm(a,b)\neq b\),则是一个答案. 否则答案是 \(b\times\frac{b}{a}\). C 先前缀和.设前缀和 \(s_i\).考虑 \(s_i\) 减 ...

  6. 【译】我为 .NET 开发人员准备的 2023 年 Visual Studio 10 大新功能

    原文 | James Montemagno 翻译 | 郑子铭 Visual Studio 2022 在 2023 年发布了许多令人难以置信的功能,为 .NET 开发人员提供了大量新工具来提高他们的工作 ...

  7. 从零开始手写 redis(四)监听器的实现

    前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...

  8. 【Unity3D】异步Socket通讯

    1 前言 ​ 同步 Socket 通讯 中的 Accept.Connect.Receive 等方法会阻塞当前线程,当前线程必须等待这些方法执行完,才会继续往下执行,用户需要另开线程执行这些耗时方法,否 ...

  9. Swoole从入门到入土(9)——TCP服务器[协程风格]

    上一篇,我们一起初步接触了协程.我相信只有一节的讨论,很多小伙伴对于"协程"与"线程"的区分可能还有点模糊.我们这里以两者的比较作为本篇开头,进行一番比较. 首 ...

  10. springboot中前端ajax如何给controller提交数组参数?

    说明 我有个需求,前端批量添加一堆商品明细.也就是说会有一个商品ID,然后一堆商品明细,多行. 如此一来,针对后端接口肯定是要以数组或列表方式接收这个商品明细数组了. 前端代码 关键地方在于以form ...