Giter VIP home page Giter VIP logo

zltoolkit's Introduction

logo

简体中文 | English

一个基于C++11的高性能运营级流媒体服务框架

项目特点

  • 基于C++11开发,避免使用裸指针,代码稳定可靠,性能优越。
  • 支持多种协议(RTSP/RTMP/HLS/HTTP-FLV/WebSocket-FLV/GB28181/HTTP-TS/WebSocket-TS/HTTP-fMP4/WebSocket-fMP4/MP4/WebRTC),支持协议互转。
  • 使用多路复用/多线程/异步网络IO模式开发,并发性能优越,支持海量客户端连接。
  • 代码经过长期大量的稳定性、性能测试,已经在线上商用验证已久。
  • 支持linux、macos、ios、android、windows全平台。
  • 支持x86、arm、risc-v、mips、龙芯、申威等指令集平台。
  • 支持画面秒开、极低延时(500毫秒内,最低可达100毫秒)。
  • 提供完善的标准C API,可以作SDK用,或供其他语言调用。
  • 提供完整的MediaServer服务器,可以免开发直接部署为商用服务器。
  • 提供完善的restful api以及web hook,支持丰富的业务逻辑。
  • 打通了视频监控协议栈与直播协议栈,对RTSP/RTMP支持都很完善。
  • 全面支持H265/H264/AAC/G711/OPUS。
  • 功能完善,支持集群、按需转协议、按需推拉流、先播后推、断连续推等功能。
  • 极致性能,单机10W级别播放器,100Gb/s级别io带宽能力。
  • 极致体验,独家特性
  • 谁在使用zlmediakit?
  • 全面支持ipv6网络
  • 支持多轨道模式(一个流中多个视频/音频)

项目定位

  • 移动嵌入式跨平台流媒体解决方案。
  • 商用级流媒体服务器。
  • 网络编程二次开发SDK。

功能清单

功能一览

功能一览
  • RTSP[S]

    • RTSP[S] 服务器,支持RTMP/MP4/HLS转RTSP[S],支持亚马逊echo show这样的设备
    • RTSP[S] 播放器,支持RTSP代理,支持生成静音音频
    • RTSP[S] 推流客户端与服务器
    • 支持 rtp over udp rtp over tcp rtp over http rtp组播 四种RTP传输方式
    • 服务器/客户端完整支持Basic/Digest方式的登录鉴权,全异步可配置化的鉴权接口
    • 支持H265编码
    • 服务器支持RTSP推流(包括rtp over udp rtp over tcp方式)
    • 支持H264/H265/AAC/G711/OPUS/MJPEG编码,其他编码能转发但不能转协议
  • RTMP[S]

    • RTMP[S] 播放服务器,支持RTSP/MP4/HLS转RTMP
    • RTMP[S] 发布服务器,支持录制发布流
    • RTMP[S] 播放器,支持RTMP代理,支持生成静音音频
    • RTMP[S] 推流客户端
    • 支持http[s]-flv直播服务器
    • 支持http[s]-flv直播播放器
    • 支持websocket-flv直播
    • 支持H264/H265/AAC/G711/OPUS编码,其他编码能转发但不能转协议
    • 支持RTMP-H265
    • 支持RTMP-OPUS
    • 支持enhanced-rtmp(H265)
  • HLS

    • 支持HLS文件(mpegts/fmp4)生成,自带HTTP文件服务器
    • 通过cookie追踪技术,可以模拟HLS播放为长连接,可以实现HLS按需拉流、播放统计等业务
    • 支持HLS播发器,支持拉流HLS转rtsp/rtmp/mp4
    • 支持H264/H265/AAC/G711/OPUS编码
    • 支持多轨道模式
  • TS

    • 支持http[s]-ts直播
    • 支持ws[s]-ts直播
    • 支持H264/H265/AAC/G711/OPUS编码
    • 支持多轨道模式
  • fMP4

    • 支持http[s]-fmp4直播
    • 支持ws[s]-fmp4直播
    • 支持H264/H265/AAC/G711/OPUS/MJPEG编码
    • 支持多轨道模式
  • HTTP[S]与WebSocket

    • 服务器支持目录索引生成,文件下载,表单提交请求
    • 客户端提供文件下载器(支持断点续传),接口请求器,文件上传器
    • 完整HTTP API服务器,可以作为web后台开发框架
    • 支持跨域访问
    • 支持http客户端、服务器cookie
    • 支持WebSocket服务器和客户端
    • 支持http文件访问鉴权
  • GB28181与RTP推流

    • 支持UDP/TCP RTP(PS/TS/ES)推流服务器,可以转换成RTSP/RTMP/HLS等协议
    • 支持RTSP/RTMP/HLS等协议转rtp推流客户端,支持TCP/UDP模式,提供相应restful api,支持主动被动方式
    • 支持H264/H265/AAC/G711/OPUS编码
    • 支持es/ps/ts/ehome rtp推流
    • 支持es/ps rtp转推
    • 支持GB28181主动拉流模式
    • 支持双向语音对讲
    • 支持多轨道模式
  • MP4点播与录制

    • 支持录制为FLV/HLS/MP4
    • RTSP/RTMP/HTTP-FLV/WS-FLV支持MP4文件点播,支持seek
    • 支持H264/H265/AAC/G711/OPUS编码
    • 支持多轨道模式
  • WebRTC

    • 支持WebRTC推流,支持转其他协议
    • 支持WebRTC播放,支持其他协议转WebRTC
    • 支持双向echo test
    • 支持simulcast推流
    • 支持上下行rtx/nack丢包重传
    • 支持单端口、多线程、客户端网络连接迁移(开源界唯一)
    • 支持TWCC rtcp动态调整码率
    • 支持remb/pli/sr/rr rtcp
    • 支持rtp扩展解析
    • 支持GOP缓冲,webrtc播放秒开
    • 支持datachannel
    • 支持webrtc over tcp模式
    • 优秀的nack、jitter buffer算法, 抗丢包能力卓越
    • 支持whip/whep协议
  • SRT支持

  • 其他

    • 支持丰富的restful api以及web hook事件
    • 支持简单的telnet调试
    • 支持配置文件热加载
    • 支持流量统计、推拉流鉴权等事件
    • 支持虚拟主机,可以隔离不同域名
    • 支持按需拉流,无人观看自动关断拉流
    • 支持先播放后推流,提高及时推流画面打开率
    • 提供完整强大的c api sdk
    • 支持FFmpeg拉流代理任意格式的流
    • 支持http api生成并返回实时截图
    • 支持按需解复用、转协议,当有人观看时才开启转协议,降低cpu占用率
    • 支持溯源模式的集群部署,溯源方式支持rtsp/rtmp/hls/http-ts, 边沿站支持hls, 源站支持多个(采用round robin方式溯源)
    • rtsp/rtmp/webrtc推流异常断开后,可以在超时时间内重连推流,播放器无感知

编译以及测试

编译前务必仔细参考wiki:快速开始操作!!!

怎么使用

你有三种方法使用ZLMediaKit,分别是:

  • 1、使用c api,作为sdk使用,请参考这里.
  • 2、作为独立的流媒体服务器使用,不想做c/c++开发的,可以参考 restful apiweb hook.
  • 3、如果想做c/c++开发,添加业务逻辑增加功能,可以参考这里的测试程序.

Docker 镜像

你可以从Docker Hub下载已经编译好的镜像并启动它:

#此镜像为github持续集成自动编译推送,跟代码(master分支)保持最新状态
docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 9000:9000/udp zlmediakit/zlmediakit:master

你也可以根据Dockerfile编译镜像:

bash build_docker_images.sh

合作项目

授权协议

本项目自有代码使用宽松的MIT协议,在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。 但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除; 由于使用本项目而产生的商业纠纷或侵权行为一概与本项目及开发者无关,请自行承担法律风险。 在使用本项目代码时,也应该在授权协议中同时表明本项目依赖的第三方库的协议。

联系方式

  • 邮箱:[email protected](本项目相关或流媒体相关问题请走issue流程,否则恕不邮件答复)
  • 请关注微信公众号获取最新消息推送:

  • 也可以自愿有偿加入知识星球咨询和获取资料:

怎么提问?

如果要对项目有相关疑问,建议您这么做:

  • 1、仔细看下readme、wiki,如果有必要可以查看下issue.
  • 2、如果您的问题还没解决,可以提issue.
  • 3、如果需要获取更及时贴心的技术支持,可以有偿加入知识星球.

特别感谢

本项目采用了老陈media-server 库, 本项目的 ts/fmp4/mp4/ps 容器格式的复用解复用都依赖media-server库。在实现本项目诸多功能时,老陈多次给予了无私热情关键的帮助, 特此对他表示诚挚的感谢!

致谢

感谢以下各位对本项目包括但不限于代码贡献、问题反馈、资金捐赠等各种方式的支持!以下排名不分先后:

老陈 Gemfield 南冠彤 凹凸慢 chenxiaolei 史前小虫 清涩绿茶 3503207480 DroidChow 阿塞 火宣 γ瑞γミ linkingvision 茄子 好心情 浮沉 Xiaofeng Wang doodoocoder qingci swwheihei KKKKK5G Zhou Weimin Jim Jin 西瓜丶 MingZhuLiu chengxiaosheng big panda tanningzhong hctym1995 hewenyuan sunhui mirs Kevin Cheng Liu Jiang along qingci lyg1949 zhlong 大裤衩 droid.chow 陈晓林 CharleyWangHZ Johnny DoubleX69 lawrencehj yangkun Xinghua Zhao hejilin rqb500 Alex Dw9 明月惊鹊 cgm hejilin alexliyu7352 cgm haorui wang joshuafc JayChen0519 zx wangcker WuPeng starry mtdxc 胡刚风 zhao85 dreamisdream dingcan Haibo Chen Leon custompal PioLing KevinZang gongluck a-ucontrol TalusL ahaooahaz TempoTian Derek Liu ljx0305 朱如洪 lijin PioLing BackT0TheFuture perara codeRATny dengjfzh 百鸣 fruit Juice tbago Luosh linxiaoyan87 waken Deepslient imp_rayjay ArmstrongCN leibnewton 1002victor Grin xbpeng121 lvchenyun Fummowo Jovial Young yujitai KisChang zjx94 LeiZhi.Mai JiaHao chdahuzi snysmtx SetoKaiba sandro-qiang Paul Philippov 张传峰 lidaofu-hub huangcaichun jamesZHANG500 weidelong 小强先生

同时感谢JetBrains对开源项目的支持,本项目使用CLion开发与调试:

JetBrains

使用案例

本项目已经得到不少公司和个人开发者的认可,据作者不完全统计, 使用本项目的公司包括知名的互联网巨头、国内排名前列的云服务公司、多家知名的AI独角兽公司, 以及一系列中小型公司。使用者可以通过在 issue 上粘贴公司的大名和相关项目介绍为本项目背书,感谢支持!

zltoolkit's People

Contributors

a-ucontrol avatar alexliyu7352 avatar baigao-x avatar baiyfcu avatar beichen2012 avatar brokensword2018 avatar bzd2132 avatar chengxiaosheng avatar coolmre avatar custompal avatar dongdan002 avatar dujingning avatar lattice0 avatar ljx0305 avatar lvchenyun avatar mc373906408 avatar mtdxc avatar musicwood avatar newbeeairfeeen avatar normalzero avatar pioling avatar sandro-qiang avatar scopys avatar shinydeng avatar vzf666 avatar wangcker avatar wasphin avatar xia-chu avatar xiongguangjie avatar zhao85 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zltoolkit's Issues

写日志的线程同步问题

写日志经常会在不同的线程同时进行,因为在写日志的时候会创建新日志文件和删除旧日志文件,当线程1在创建新日志文件的时候,而线程2同时删除旧日志文件,程序就会崩溃,建议作者修改此bug

Socket类里的_mtx_socket问题

正在分析作者的网络库 对Socket的成员_mtx_socket很疑惑
TcpServer.h中

virtual Socket::Ptr onBeforeAcceptConnection(const EventPoller::Ptr &poller){
        /**
         * 服务器器模型socket是线程安全的,所以为了提高性能,关闭互斥锁
         */
        return std::make_shared<Socket>(poller,false);
    }

服务器模型是线程安全的 因为socket的读/写/超时/关闭 都是在一个线程中顺序执行的 不需要互斥量 所以为了提高性能 关闭互斥锁
那么非服务器模型 为什么线程不安全的呢? 具体而言就是

commit a549490e Jzan <[email protected]> on 3/5/17 at 6:20 PM

是基于什么场景呢?

# 代码请教

图片
logger里的函数Instance()没有定义,为什么可以直接使用呢?有大佬可以提点一二吗。

如何使用ZLToolKit构建高性能的媒体转发服务器

背景需求:
应用场景类似互动聊天直播室,可能有1-8个同时说话(视频)的嘉宾,还有n个观众。服务器将嘉宾上传的udp媒体数据包转发给房间其余人。
还有一点简单信令,比如进房间,离开房间,上嘉宾位,离开嘉宾位(变成观众)等,这部分打算用TCP做。
房间之间是相互独立的,一个服务器需要同时支持很多个房间,所以对UDP的性能要求会高,tcp只是信令以及长连接维持。UDP媒体数据包头会包含房间号和用户uid。
问题如下:
1、UDP的使用参考test_udpSock.cpp即可吗,对于我们这种场景需求,zltoolkit的使用上有没什么其他的注意,比如避免内存拷贝等事项?
2、将一个包转发给房间其他人,是自己维护一个房间所有人的udp地址列表,然后遍历发送吗,zltoolkit有没什么其他更高端高效率的办法?
3、关于房间数据结构的查找问题,目前是打算用一个udp端口进行监听,udp数据包头带上房间号,解析包头得到房间号,然后通过map查找到这个房间的数据结构;另外一种方式是,一个房间使用一个udp端口进行监听,这样这个udp端口收到的数据天然就是这个房间的,避免了我们使用map查找房间。请问这两种方式,哪种房间数量多了性能会好些呢?

./test_ringBuffer terminate called without an active exception

ubuntu18.04 运行test_ringBuffer时候出错,调试log如下:

vroot@vroot-ThinkPad-E14:~/604/ZLToolKit/build$ gdb ./bin/test_ringBuffer 



(gdb) r
Starting program: /home/vroot/604/ZLToolKit/build/bin/test_ringBuffer 
warning: File "/usr/share/gdb/auto-load/lib/x86_64-linux-gnu/libpthread-2.27.so-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "/home/vroot/".
To enable execution of this file add
        add-auto-load-safe-path /usr/share/gdb/auto-load/lib/x86_64-linux-gnu/libpthread-2.27.so-gdb.py
line to your configuration file "/home/vroot/.gdbinit".
To completely disable this security protection add
        set auto-load safe-path /
line to your configuration file "/home/vroot/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
        info "(gdb)Auto-loading safe path"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
warning: File "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "/home/vroot/".
[New Thread 0x7ffff5985700 (LWP 24791)]
[New Thread 0x7ffff5184700 (LWP 24792)]
2021-01-04 10:48:04.463 D test_ringBuffer[24784] util.cpp:324 operator() | Stamp thread started!
[New Thread 0x7ffff4983700 (LWP 24793)]
[New Thread 0x7fffe7fff700 (LWP 24794)]
[New Thread 0x7fffe77fe700 (LWP 24795)]
[New Thread 0x7fffe6ffd700 (LWP 24796)]
[New Thread 0x7fffe67fc700 (LWP 24797)]
[New Thread 0x7fffe5ffb700 (LWP 24798)]
[New Thread 0x7fffe57fa700 (LWP 24799)]
[New Thread 0x7fffe4ff9700 (LWP 24800)]
2021-01-04 10:48:04.465 I test_ringBuffer[24784] EventPoller.cpp:466 EventPollerPool | 创建EventPoller个数:8
[New Thread 0x7fffc7fff700 (LWP 24801)]
2021-01-04 10:48:04.465 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 1
2021-01-04 10:48:04.565 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 2
2021-01-04 10:48:04.666 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 3
2021-01-04 10:48:04.766 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 4
2021-01-04 10:48:04.866 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 5
2021-01-04 10:48:04.966 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 6
2021-01-04 10:48:05.067 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 7
2021-01-04 10:48:05.167 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 8
2021-01-04 10:48:05.267 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 9
2021-01-04 10:48:05.367 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 10
2021-01-04 10:48:05.467 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 11
2021-01-04 10:48:05.568 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 12
2021-01-04 10:48:05.668 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 13
2021-01-04 10:48:05.768 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 14
2021-01-04 10:48:05.868 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 15
2021-01-04 10:48:05.969 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 16
2021-01-04 10:48:06.069 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 17
2021-01-04 10:48:06.169 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 18
2021-01-04 10:48:06.269 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 19
2021-01-04 10:48:06.369 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 20
2021-01-04 10:48:06.470 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 21
2021-01-04 10:48:06.570 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 22
2021-01-04 10:48:06.670 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 23
2021-01-04 10:48:06.770 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 24
2021-01-04 10:48:06.871 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 25
2021-01-04 10:48:06.971 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 26
2021-01-04 10:48:07.071 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 27
2021-01-04 10:48:07.171 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 28
2021-01-04 10:48:07.271 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 29
2021-01-04 10:48:07.372 D test_ringBuffer[24784] test_ringBuffer.cpp:31 onReadEvent | 30
[Thread 0x7fffc7fff700 (LWP 24801) exited]
2021-01-04 10:48:07.472 W test_ringBuffer[24784] test_ringBuffer.cpp:36 onDetachEvent | 
terminate called without an active exception
[Thread 0x7fffe7fff700 (LWP 24794) exited]
2021-01-04 10:48:08.473 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e62e0
2021-01-04 10:48:08.473 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e67a0
2021-01-04 10:48:08.474 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e6c60
2021-01-04 10:48:08.474 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e70c0
2021-01-04 10:48:08.475 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e75e0
2021-01-04 10:48:08.475 I test_ringBuffer[24784] EventPoller.cpp:95 ~EventPoller | 0x5555557e7a70
[Thread 0x7fffe57fa700 (LWP 24799) exited]
[Thread 0x7fffe67fc700 (LWP 24797) exited]
[Thread 0x7fffe5ffb700 (LWP 24798) exited]
[Thread 0x7fffe77fe700 (LWP 24795) exited]
[Thread 0x7fffe6ffd700 (LWP 24796) exited]

Thread 4 "test_ringBuffer" received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff4983700 (LWP 24793)]
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.





(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff6e95921 in __GI_abort () at abort.c:79
#2  0x00007ffff74ea957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff74f0ae6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff74f0b21 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00005555555a7993 in std::thread::~thread() ()
#6  0x00007ffff7b39341 in toolkit::EventPoller::shutdown() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#7  0x00007ffff7b393d8 in toolkit::EventPoller::~EventPoller() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#8  0x00007ffff7b39552 in toolkit::EventPoller::~EventPoller() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#9  0x00007ffff7b4bdaa in std::_Sp_counted_ptr<toolkit::EventPoller*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#10 0x00005555555aa92c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
#11 0x00005555555a8af9 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() ()
#12 0x00005555555a879e in std::__shared_ptr<toolkit::EventPoller, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() ()
#13 0x00005555555a87ba in std::shared_ptr<toolkit::EventPoller>::~shared_ptr() ()
#14 0x00005555555aa110 in toolkit::RingBuffer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#2}::~_RingReaderDispatcher() ()
#15 0x00005555555b9652 in std::_Sp_ebo_helper<0, toolkit::RingBuffer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#2}, false>::~_Sp_ebo_helper() ()
#16 0x00005555555b966e in std::_Sp_counted_deleter<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, toolkit::RingBuffer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#2}, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_Impl::~_Impl() ()
#17 0x00005555555be6c6 in std::_Sp_counted_deleter<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, toolkit::RingBuffer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#2}, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::~_Sp_counted_deleter() ()
#18 0x00005555555be792 in std::_Sp_counted_deleter<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, toolkit::RingBuffer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#2}, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>::_M_destroy() ()
#19 0x00005555555ad71e in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_weak_release() ()
#20 0x00005555555ab18f in std::__weak_count<(__gnu_cxx::_Lock_policy)2>::~__weak_count() ()
#21 0x00005555555ac478 in std::__weak_ptr<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, (__gnu_cxx::_Lock_policy)2>::~__weak_ptr() ()
#22 0x00005555555ac494 in std::weak_ptr<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~weak_ptr() ()
#23 0x00005555555ac74c in toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#1}::operator()(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) const::{lambda()#1}::~_RingReader() ()
#24 0x00005555555b625e in std::_Function_base::_Base_manager<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#1}::operator()(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) const::{lambda()#1}>::_M_destroy(std::_Any_data&, std::integral_constant<bool, false>) ()
#25 0x00005555555b250c in std::_Function_base::_Base_manager<toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#1}::operator()(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) const::{lambda()#1}>::_M_manager(std::_Any_data&, toolkit::_RingReaderDispatcher<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::attach(std::shared_ptr<toolkit::EventPoller> const&, bool)::{lambda(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)#1}::operator()(toolkit::_RingReader<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*) const::{lambda()#1} const&, std::_Manager_operation) ()
#26 0x00005555555a7fc3 in std::_Function_base::~_Function_base() ()
#27 0x00005555555a7ff6 in std::function<void ()>::~function() ()
#28 0x00007ffff7b4c17e in void __gnu_cxx::new_allocator<std::function<void ()> >::destroy<std::function<void ()> >(std::function<void ()>*) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#29 0x00007ffff7b4bfbf in void std::allocator_traits<std::allocator<std::function<void ()> > >::destroy<std::function<void ()> >(std::allocator<std::function<void ()> >&, std::function<void ()>*) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#30 0x00007ffff7b4b83d in std::_Sp_counted_ptr_inplace<std::function<void ()>, std::allocator<std::function<void ()> >, (__gnu_cxx::_Lock_policy)2>::_M_dispose() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#31 0x00005555555aa92c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
#32 0x00005555555a8af9 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() ()
#33 0x00007ffff7b3ede8 in std::__shared_ptr<std::function<void ()>, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#34 0x00007ffff7b3ee04 in std::shared_ptr<std::function<void ()> >::~shared_ptr() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#35 0x00007ffff7b4b5dc in toolkit::TaskCancelableImp<void ()>::~TaskCancelableImp() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#36 0x00007ffff7b4c1e7 in void __gnu_cxx::new_allocator<toolkit::TaskCancelableImp<void ()> >::destroy<toolkit::TaskCancelableImp<void ()> >(toolkit::TaskCancelableImp<void ()>*) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#37 0x00007ffff7b4c03f in void std::allocator_traits<std::allocator<toolkit::TaskCancelableImp<void ()> > >::destroy<toolkit::TaskCancelableImp<void ()> >(std::allocator<toolkit::TaskCancelableImp<void ()> >&, toolkit::TaskCancelableImp<void ()>*) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#38 0x00007ffff7b4bb25 in std::_Sp_counted_ptr_inplace<toolkit::TaskCancelableImp<void ()>, std::allocator<toolkit::TaskCancelableImp<void ()> >, (__gnu_cxx::_Lock_policy)2>::_M_dispose() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#39 0x00005555555aa92c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
#40 0x00005555555a8af9 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() ()
#41 0x00005555555a809e in std::__shared_ptr<toolkit::TaskCancelableImp<void ()>, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() ()
#42 0x00005555555a80ba in std::shared_ptr<toolkit::TaskCancelableImp<void ()> >::~shared_ptr() ()
#43 0x00007ffff7b42628 in toolkit::ListNode<std::shared_ptr<toolkit::TaskCancelableImp<void ()> > >::~ListNode() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#44 0x00007ffff7b40950 in toolkit::List<std::shared_ptr<toolkit::TaskCancelableImp<void ()> > >::clear() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#45 0x00007ffff7b3ec68 in toolkit::List<std::shared_ptr<toolkit::TaskCancelableImp<void ()> > >::~List() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#46 0x00007ffff7b3e2f7 in toolkit::EventPoller::onPipeEvent() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#47 0x00007ffff7b38d96 in toolkit::EventPoller::EventPoller(toolkit::ThreadPool::Priority)::{lambda(int)#1}::operator()(int) const () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#48 0x00007ffff7b3ba03 in std::_Function_handler<void (int), toolkit::EventPoller::EventPoller(toolkit::ThreadPool::Priority)::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#49 0x00005555555ae4de in std::function<void (int)>::operator()(int) const ()
#50 0x00007ffff7b3a831 in toolkit::EventPoller::runLoop(bool, bool) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#51 0x00007ffff7b41b01 in void std::__invoke_impl<void, void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool>(std::__invoke_memfun_deref, void (toolkit::EventPoller::*&&)(bool, bool), toolkit::EventPoller*&&, bool&&, bool&&) ()
   from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#52 0x00007ffff7b3fd1b in std::__invoke_result<void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool>::type std::__invoke<void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool>(void (toolkit::EventPoller::*&&)(bool, bool), toolkit::EventPoller*&&, bool&&, bool&&) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#53 0x00007ffff7b4c283 in decltype (__invoke((_S_declval<0ul>)(), (_S_declval<1ul>)(), (_S_declval<2ul>)(), (_S_declval<3ul>)())) std::thread::_Invoker<std::tuple<void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool> >::_M_invoke<0ul, 1ul, 2ul, 3ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul>) () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#54 0x00007ffff7b4c0ae in std::thread::_Invoker<std::tuple<void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool> >::operator()() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#55 0x00007ffff7b4be72 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (toolkit::EventPoller::*)(bool, bool), toolkit::EventPoller*, bool, bool> > >::_M_run() () from /home/vroot/604/ZLToolKit/build/lib/libZLToolKit.so
#56 0x00007ffff751b6df in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#57 0x00007ffff77ee6db in start_thread (arg=0x7ffff4983700) at pthread_create.c:463
#58 0x00007ffff6f7671f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) 

关于用EventPollerPool::Instance().getPoller()->doDelayTask() EventPollerPool::Instance().getPoller()->async()做心跳线程的问题

现在要实现一个http短链接心跳接口,

方法1:失败

url.append("/acd/api/v1/0/agent/heartbeat");
weak_ptr<WebClient> weakSelf = dynamic_pointer_cast<WebClient>(_client);
EventPollerPool::Instance().getPoller()->async([weakSelf, url]() {
    while (true) {
        sleep(10);
        auto strongSelf=weakSelf.lock();
        if(strongSelf){
            strongSelf->heartbeat(str);
        }
    }
}, true);

方法2:失败

EventPollerPool::Instance().getPoller()->doDelayTask(10 * 1000, [weakSelf, url]() {
                auto strongSelf=weakSelf.lock();
                if(strongSelf){
                    strongSelf->heartbeat(str);
                }
                sleep(10);
                return true;
            });

这是heartbeat()的实现方法

void WebClient::heartbeat(const string &url){
    //TraceL << url;
    _heartbeatPost.reset(new HttpRequester);
    _heartbeatPost->setMethod("POST");
    //设置http请求头
    _heartbeatPost->addHeader("Content-Type", "application/json");
    //设置POST参数列表
    Value val;
    val["groupId"] = _groupId;
    val["agentId"] = _agentId;
    _heartbeatPost->setBody(val.toStyledString());
    //InfoL << val.toStyledString();
    //开启请求
    _heartbeatPost->startRequester(url,//url地址
                                   [](const SockException &ex,                          //网络相关的失败信息,如果为空就代表成功
                                      const string &status,                             //http回复的状态码,比如说200/404
                                      const HttpClient::HttpHeader &header,             //http回复头
                                      const string &strRecvBody) {                       //http回复body
                                       //DebugL << "=====================HttpRequester POST==========================";
                                       if (ex) {
                                           //网络相关的错误
                                           WarnL << "heartbeat network err:" << ex.getErrCode() << " " << ex.what();
                                       } else {
                                           TraceL << "heartbeat body:" << strRecvBody;
                                       }
                                   });
}

_heartbeatPost申请的是全局变量,但是http包都发不出去.
现在用的方法是申请一个thread,放进去实现,但是这样写太难看了,请问有什么好方法用EventPollerPool::Instance().getPoller()发http的心跳请求,

历史日志文件清除失败

如果程序一直运行,并只设置了一天保留,在第二天时并不会删除第一天产生的文件,这是我临时修改的代码
image

持续读会撑爆内存

当一个连接来的速度很快,多到超过实际处理速度。比如一个server接受上传文件。客户端以1G的速度上传文件,但是该server只能以每秒100M的速度写文件。这种情况下,server会持续的通过epoll读,最终撑爆内存。
当server发现自己缓存的内存已经超过一定阈值,它不能持续read直到EAGAIN。如果是EDGE触发,它得在自己消费完了缓存的内存之后再read,如果是LEVEL触发,它得调用epoll_ctl删除这个fd,并且在自己消费完了缓存的内存之后再加入这个fd。
当server不再read时,tcp协议栈会降低tcp wnd,从而抑制发送方的发送速度。

你这个库里似乎并没有这个逻辑。

qml c++异常错误

qml 里面只要 Socket::Ptr sockRecv(new Socket());//创建一个UDP端口,然后关闭程序会报这样的错误
Exception at 0x743e4592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\poller\eventpoller.cpp:87

接收长字符串问题

在用测试例子tcp client和echo server传输由图片转成的base64字符串时,服务器端接收的字符串总是丢失一大段字符串
image
在上面的里打印buf->data()的长度发现与client发送的不一致,小了很多

非常感谢大佬的作品,

_sessionMap 一致性问题?

void onManagerSession() {
for (auto &pr : _sessionMap) {
weak_ptr weakSession = pr.second->session();
pr.second->session()->async(weakSession {
auto strongSession=weakSession.lock();
if(!strongSession) {
return;
}
strongSession->onManager();
}, false);
}
}

请问 在处理这个sessionmap的时候 我卡你这个时候遍历 还是这个seessionmap的添加删除 都没用锁,如果这个seesion遍历的过程中,map被添加或者删除了怎么办,这个是怎么保持一致性的?每太搞明白

关于ThreadLoadCounter统计问题

ThreadPool(int num = 1, Priority priority = PRIORITY_HIGHEST, bool autoRun = true) ;

ThreadPool允许创建多条线程. 在ThreadPool::run()中调用startSleep()与sleepWakeUp()进行load统计,当线程数大于1时,load统计是否不准确?

请教TCP拆包和粘包的处理解决办法

我仔细看了您流媒体服务器中HTTP中关于TCP合包的代码,但是无论才疏学浅,没有很明白,希望作者可以大概讲解下TCP处理拆包粘包的思路,现在基于ZLToolKit要实现一个大文件收发,出现拆包粘包问题.
另外我现在需要实现http上传文件,您的http里面有实现好的吗?或者告诉我一个解决思路,非常感谢

poller线程的问题

比如我现在4核的机器,我启动的4个poller,但是我每次getpoller都是随机的,我如何能保证我一个数据只能在一个poller里面执行,如果是几个poller循环执行,会不会导致执行顺序不对导致数据不对的现象?

error C2872: “byte”: 不明确的符号

1>util.cpp
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\rpcndr.h(192,14): error C2872: “byte”: 不明确的符号
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\rpcndr.h(191,23): message : 可能是“unsigned char byte”
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.28.29333\include\cstddef(29,12): message : 或 “std::byte”
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\rpcndr.h(962,25): error C2872: “byte”: 不明确的符号
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared\rpcndr.h(191,23): message : 可能是“unsigned char byte”

Windows下关于 g_defaultLogger 的编译问题

VS2017,到编译 ALL_BUILD 时,出现如下问题:

test_logger.obj : error LNK2019: 无法解析的外部符号 "class toolkit::Logger * toolkit::g_defaultLogger" (?g_defaultLogger@toolkit@@3PAVLogger@1@A),该符号在函数 _main 中被引用

test_delayTask.obj : error LNK2019: 无法解析的外部符号 "class toolkit::Logger * toolkit::g_defaultLogger" (?g_defaultLogger@toolkit@@3PAVLogger@1@A),该符号在函数 "private: virtual void __thiscall std::_Func_impl_no_alloc<class <lambda_1f860e808c4732d9497d62aaa8d648d8>,void>::_Do_call(void)" (?_Do_call@?$_Func_impl_no_alloc@V<lambda_1f860e808c4732d9497d62aaa8d648d8>@@x$$V@std@@EAEXXZ) 中被引用

...

请问是test项目的引用有问题吗

当我退出进程后遇到这些打印的问题

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

Exception at 0x75264592, code: 0xe06d7363: C++ exception, flags=0x1 (execution cannot be continued) (first chance) at e:\xxxx\kitlib\poller\eventpoller.cpp:87

目前不知道该原因是什么意思

新建多个tcpclient发送消息丢包问题

我新建了个一些tcpclient 向这个demo的tcpehcosession 发送消息,然后服务器在将消息返回,但是我发现每次收到的消息都少,通过网卡抓包 消息是回到了client的 不知道什么原因没上来,另外 这个时候我control+c tcpehcosession,这面客户端收感觉丢的消息这个时候就都上来了,请帮我看看

附上client的代码 tcpechosession 就负责回消息,啥都不干

int main() {
// 设置日志系统
Logger::Instance().add(std::make_shared());
Logger::Instance().add(std::make_shared());
Logger::Instance().setWriter(std::make_shared());
for (int i = 0; i < 200; i++)
{
TestClient::Ptr client(new TestClient());//必须使用智能指针
client->startConnect("192.168.1.189", 40996);//连接服务器
testmap.emplace(i, client);
}
sleep(30);
for (auto it = testmap.begin(); it != testmap.end(); it++)
{
it->second->send("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
}

udp 是否有类似 TcpServer 的性能优化

目前看 udp server 主要看主要是在 rtsp 及 rtpproxy 部分用到, 对性能要求可能不高.

我这边的情况是需要一个及主要通过 udp 接入的服务器, 这边是否有类似 TcpServer 这样的优化方案呢?

这里只有一个 tcp 的 connect 接口
https://github.com/xiongziliang/ZLToolKit/blob/ed47015f92cc79dfe3344b3666aafb54f1bbc2f4/src/Network/sockutil.h#L62

udp 也可以 connect

   If the socket sockfd is of type SOCK_DGRAM, then addr is the address to
   which datagrams are sent by default, and the only  address  from  which
   datagrams  are  received.   If  the  socket  is  of type SOCK_STREAM or
   SOCK_SEQPACKET, this call attempts to make a connection to  the  socket
   that is bound to the address specified by addr.

这样如果双向 connect 一下, 是否可以实现类似 TcpServer 中的效果? 这部分相关的改动如果有的话, 是否会考虑合到项目中?

ini文件写问题

ini配置文件 使用mINI如何更新到文件
我这样使用
mINI::Instance()["rtp_proxy.port"] = 1233; mINI::Instance()[RtpProxy::kPort] = 1234;
ini文件没有保存 怎样做可以更新到文件

关于 sqlpool

请问下 这个数据库的轮子可以弄成多实例的么 就可以连接几个IP 几个Database的那种

logger中,因为时区问题,会导致今天的日志,写在昨天的文件中。

问题:

logger中,因为时区问题,会导致今天的日志,写在昨天的文件中。

分支

master

平台

windows

原因:

https://github.com/xia-chu/ZLToolKit/blob/master/src/Util/logger.cpp#L406
auto day = getDay(ctx->_tv.tv_sec); 这里使用的是UTC时间。

导致后续的判断if (day != _last_day) 在 +8时区的时间内,将日志文件写入前一天时间 。

比如今天20200804,在北京时间 20200804,00-08h时间内,都属于20200803的UTC时间。

导致北京时间00-08h的日志,写入了2020-08-03.log 文件中。

使用tcpclient和TcpServer发现大量网络拥塞

在用tcpclient和TcpServer的时候发现用大量TCP Out-of-Order,TCP ACKed unseen segment,Tcp dup ack包,还是在局域网情况下测试
请问这正常吗?您对TCP的网络拥塞,乱序问题处理有什么好方法?

编译失败

环境是 ubuntu 17.10 64bit
gcc 版本 gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3.2)

错误记录如下:

./build_for_linux.sh
-- 找到openssl库:"/usr/include",ENABLE_OPENSSL宏已打开
-- Found MySQL: /usr/include, /usr/lib/x86_64-linux-gnu/libmysqlclient.so
-- MySQL Embedded not found.
-- 找到mysqlclient库:"/usr/include",ENABLE_MYSQL宏已打开
-- 将链接依赖库:/usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so;/usr/lib/x86_64-linux-gnu/libmysqlclient.so
-- 添加测试程序:test_asyncTaskThrad
-- 添加测试程序:test_eventPoller
-- 添加测试程序:test_logger
-- 添加测试程序:test_noticeCenter
-- 添加测试程序:test_pipe
-- 添加测试程序:test_resourcePool
-- 添加测试程序:test_ringBuffer
-- 添加测试程序:test_rwmutex
-- 添加测试程序:test_semaphore
-- 添加测试程序:test_shell
-- 添加测试程序:test_spin_mutex
-- 添加测试程序:test_sql
-- 添加测试程序:test_ssl
-- 添加测试程序:test_tcpClient
-- 添加测试程序:test_tcpEchoServer
-- 添加测试程序:test_threadPool
-- 添加测试程序:test_threadPoolBenchmark
-- 添加测试程序:test_udpSock
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zhang/src/cpp/ZLToolKit/linux_build
[  1%] Building CXX object CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o
[  1%] Building CXX object CMakeFiles/ZLToolKit_shared.dir/src/Util/SqlConnection.cpp.o
[  1%] Building CXX object CMakeFiles/ZLToolKit_static.dir/src/Thread/AsyncTaskThread.cpp.o
[  1%] Building CXX object CMakeFiles/ZLToolKit_static.dir/src/Util/File.cpp.o
In file included from /home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:27:0:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:50:2: error: ‘function’ does not name a type; did you mean ‘union’?
  function<bool()> task;
  ^~~~~~~~
  union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:62: error: ‘function’ does not name a type; did you mean ‘union’?
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                              ^~~~~~~~
                                                              union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:70: error: expected ‘,’ or ‘...’ before ‘<’ token
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                                      ^
In file included from /home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:27:0:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:50:2: error: ‘function’ does not name a type; did you mean ‘union’?
  function<bool()> task;
  ^~~~~~~~
  union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:62: error: ‘function’ does not name a type; did you mean ‘union’?
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                              ^~~~~~~~
                                                              union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:70: error: expected ‘,’ or ‘...’ before ‘<’ token
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                                      ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:45: error: ‘function’ does not name a type; did you mean ‘union’?
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                             ^~~~~~~~
                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:53: error: expected ‘,’ or ‘...’ before ‘<’ token
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h: In constructor ‘ZL::Thread::AsyncTaskHelper::AsyncTaskHelper(uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:84:88: error: ‘task’ was not declared in this scope
   AsyncTaskThread::Instance().DoTaskDelay(reinterpret_cast<uint64_t>(this),millisecond,task);
                                                                                        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: At global scope:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:77: error: ‘function’ does not name a type; did you mean ‘union’?
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                             ^~~~~~~~
                                                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:85: error: expected ‘,’ or ‘...’ before ‘<’ token
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTaskDelay(uint64_t, uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:8: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
  info->task = func;
        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: error: ‘func’ was not declared in this scope
  info->task = func;
               ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: note: suggested alternative: ‘sync’
  info->task = func;
               ^~~~
               sync
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:45: error: ‘function’ does not name a type; did you mean ‘union’?
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                             ^~~~~~~~
                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:53: error: expected ‘,’ or ‘...’ before ‘<’ token
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h: In constructor ‘ZL::Thread::AsyncTaskHelper::AsyncTaskHelper(uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:84:88: error: ‘task’ was not declared in this scope
   AsyncTaskThread::Instance().DoTaskDelay(reinterpret_cast<uint64_t>(this),millisecond,task);
                                                                                        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTask()’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:100:18: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
     flag = info->task();
                  ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: At global scope:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:77: error: ‘function’ does not name a type; did you mean ‘union’?
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                             ^~~~~~~~
                                                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:85: error: expected ‘,’ or ‘...’ before ‘<’ token
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTaskDelay(uint64_t, uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:8: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
  info->task = func;
        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: error: ‘func’ was not declared in this scope
  info->task = func;
               ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: note: suggested alternative: ‘sync’
  info->task = func;
               ^~~~
               sync
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTask()’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:100:18: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
     flag = info->task();
                  ^~~~
[  1%] Building CXX object CMakeFiles/ZLToolKit_shared.dir/src/Util/util.cpp.o
[  1%] Building CXX object CMakeFiles/ZLToolKit_static.dir/src/Util/MD5.cpp.o
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-predefined-identifier-outside-function’
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-predefined-identifier-outside-function’
CMakeFiles/ZLToolKit_shared.dir/build.make:254: recipe for target 'CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o' failed
make[2]: *** [CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
CMakeFiles/ZLToolKit_static.dir/build.make:254: recipe for target 'CMakeFiles/ZLToolKit_static.dir/src/Thread/AsyncTaskThread.cpp.o' failed
make[2]: *** [CMakeFiles/ZLToolKit_static.dir/src/Thread/AsyncTaskThread.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
[  1%] Building CXX object CMakeFiles/ZLToolKit_static.dir/src/Util/SSLBox.cpp.o
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/ZLToolKit_shared.dir/all' failed
make[1]: *** [CMakeFiles/ZLToolKit_shared.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/ZLToolKit_static.dir/all' failed
make[1]: *** [CMakeFiles/ZLToolKit_static.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
[  1%] Building CXX object CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o
In file included from /home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:27:0:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:50:2: error: ‘function’ does not name a type; did you mean ‘union’?
  function<bool()> task;
  ^~~~~~~~
  union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:62: error: ‘function’ does not name a type; did you mean ‘union’?
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                              ^~~~~~~~
                                                              union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:59:70: error: expected ‘,’ or ‘...’ before ‘<’ token
  void DoTaskDelay(uint64_t type, uint64_t millisecond, const function<bool()> &func);
                                                                      ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:45: error: ‘function’ does not name a type; did you mean ‘union’?
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                             ^~~~~~~~
                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:83:53: error: expected ‘,’ or ‘...’ before ‘<’ token
  AsyncTaskHelper(uint64_t millisecond,const function<bool()> &task){
                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h: In constructor ‘ZL::Thread::AsyncTaskHelper::AsyncTaskHelper(uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.h:84:88: error: ‘task’ was not declared in this scope
   AsyncTaskThread::Instance().DoTaskDelay(reinterpret_cast<uint64_t>(this),millisecond,task);
                                                                                        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: At global scope:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:77: error: ‘function’ does not name a type; did you mean ‘union’?
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                             ^~~~~~~~
                                                                             union
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:50:85: error: expected ‘,’ or ‘...’ before ‘<’ token
 void AsyncTaskThread::DoTaskDelay(uint64_t type, uint64_t millisecond,const function<bool()> &func) {
                                                                                     ^
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTaskDelay(uint64_t, uint64_t, int)’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:8: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
  info->task = func;
        ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: error: ‘func’ was not declared in this scope
  info->task = func;
               ^~~~
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:55:15: note: suggested alternative: ‘sync’
  info->task = func;
               ^~~~
               sync
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp: In member function ‘void ZL::Thread::AsyncTaskThread::DoTask()’:
/home/zhang/src/cpp/ZLToolKit/src/Thread/AsyncTaskThread.cpp:100:18: error: ‘using element_type = struct ZL::Thread::TaskInfo {aka struct ZL::Thread::TaskInfo}’ has no member named ‘task’
     flag = info->task();
                  ^~~~
At global scope:
cc1plus: warning: unrecognized command line option ‘-Wno-predefined-identifier-outside-function’
CMakeFiles/ZLToolKit_shared.dir/build.make:254: recipe for target 'CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o' failed
make[2]: *** [CMakeFiles/ZLToolKit_shared.dir/src/Thread/AsyncTaskThread.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/ZLToolKit_shared.dir/all' failed
make[1]: *** [CMakeFiles/ZLToolKit_shared.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

看上去像是function模板不支持,应该怎么办?

安卓编译报错

  • ndk 是 android-ndk-r14b
  • 系统是 macOS Big Sur 11.5.2

在 ZLToolKit 目录下直接运行 build_for_android.sh,报以下错误

ZLToolKit/src/Network/Session.cpp: In member function 'virtual std::string toolkit::Session::getIdentifier() const':
ZLToolKit/src/Network/Session.cpp:21:12: error: 'to_string' is not a member of 'std'
     return std::to_string(reinterpret_cast<uint64_t>(this));
            ^
ZLToolKit/src/Network/Session.cpp:21:12: note: suggested alternative:
In file included from ZLToolKit/src/Network/Socket.h:22:0,
                 from ZLToolKit/src/Network/Session.h:16,
                 from ZLToolKit/src/Network/Session.cpp:11:
ZLToolKit/src/Util/util.h:209:13: note:   'toolkit::to_string'
 std::string to_string(T value){
             ^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-predefined-identifier-outside-function"
make[2]: *** [CMakeFiles/ZLToolKit_static.dir/src/Network/Session.cpp.o] Error 1
make[1]: *** [CMakeFiles/ZLToolKit_static.dir/all] Error 2
make: *** [all] Error 2

send方法是线程安全的吗

多个线程都同时调用了send方法,比如:
Thread A: send("hello");
Thread B: send("world");
Thread C: send("china");
发出去的顺序或者接收到的,不可能存在这种情况吧:"hechillonaworld"。
send的buffer是原子性不可分割的。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.