早些年还在使用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. 【题解】T378828 位运算

    位运算 题目背景 题目由 daiyulong20120222 创作(me) 并由 QBW1117完善以及数据 . 题目描述 给定两个数\(x,y\) ,在给定一个位运算符号 \(c\). 请你列出 \ ...

  2. MySQL最左匹配原则

    最左匹配原则都是针对联合索引来说的,那么为什么要使用联合索引呢? 一.为什么要使用联合索引? 1.减少开销. 建一个联合索引(col1,col2,col3),实际相当于建了(col1),(col1,c ...

  3. Python-pymysql查询MySQL的表

    一.安装pymysql py -m pip install pymysql; 二.创建表并插入数据 CREATE TABLE `course` ( `course_id` varchar(10) DE ...

  4. Java并发编程-CompletableFuture(下)

    大家好,我是小高先生,书接上文,我们继续来学习CompletableFuture.上文我们讲了基础装Future是如何升级为神装CompletableFuture以及如何购买CompletableFu ...

  5. 【Unity3D】地形Terrain

    1 前言 ​ Terrain 是 Unity3D 提供的用于绘制地形的游戏对象,可以在其上绘制山地.江海.池塘.草树等. ​ 用户可以通过[GameObject → 3D Object → Terra ...

  6. 【OpenGL ES】绘制圆形

    1 前言 ​ [OpenGL ES]绘制三角形 中介绍了绘制三角形的方法,[OpenGL ES]绘制正方形中介绍了绘制正方形的方法,本文将介绍绘制圆形的方法. ​ OpenGL 以点.线段.三角形为图 ...

  7. 面试官不按套路出牌,上来就让聊一聊Java中的迭代器(Iterator ),夺命连环问,怎么办?

    写在开头 某大厂的面试现场,一位目光深邃,头顶稀疏的中年面试官坐在椅子上,这时候的我走了进来. 面试官:"小伙子,学过Java中容器和数据结构了吧?" 我:"嗯,学了&q ...

  8. C++ 快速加载 Dll 里的 API

    最近项目里要重新编写程序加载器,也就是编译出一个可执行文件,在 Windows 上是 .exe 为什么要程序加载器? 个人理解是,可执行文件大小最好是越小越好,功能都可以由 dll 文件执行 而程序加 ...

  9. windbg 学习

    常用的 windbg 命令 .ecxr 用来切换到异常发生时的上下文,主要用在分析静态 dump 文件的时候.当我们使用 .reload 命令去强制加载库的 pdb 文件后,需要执行 .ecxr 命令 ...

  10. TCP/IP的确认号,序列号和超时重传的学习笔记

    一:确认应答和序列号 在tcp中,发送端的数据到达主机时,接收端会返回一个已收到的通知.这个消息叫做确认应答(ACK). 当发送端发送数据后,会等待对端的确认应答.如果有确认应答,说明数据已经成功到达 ...