Xu Zhipei
Xu Zhipei
在上次的 [RTSP 协议详解](https://github.com/xizhibei/blog/issues/152) 中,把 RTSP 协议本身简单介绍了,这次就来说说如何实现一个简单的 RTSP 服务器。 ### Live555 Live555 是我们经常用的 C++ 媒体库,它支持非常多的媒体服务协议,实现了对多种音视频编码格式的音视频数据的数据流化、接收和处理等支持。 它也是现在为数不多的可用库之一,它的代码比较繁琐,但是胜在简单,多数人拿到之后就能简单上手了,因此也非常适合拿来练手,以及改写。 ### 一个简单的 RTSP/H264 实现 我们拿 `testProgs/testOnDemandRTSPServer.cpp` 作为例子。 首先创建 RTSP 服务本身: ```c++ TaskScheduler* scheduler = BasicTaskScheduler::createNew();...
今年最大的体会,就是体力与精力的双重下降:身体上颈椎与腰椎都有问题,下半年经常心悸跟腰背疼,去推拿了好几次,年底了又多了个干眼症。 另外,我的精力已经从纯技术路线转移了。 ### 创业 今年的疫情依然没有结束,但是我所在的公司开始做防疫相关的产品了,于是我们这一年来成长了不少,业务也真正有起色了。 不过,成功是有代价的,尽管目前只是小成功。 感觉自己的体力与精力最明显的下降是在 8 月份时候,因为那时候遇到了一波比较大的本土疫情,而我们公司的订单量也开始上升,但是我们却遇到了产品方面的问题,于是几乎每天都在加班加点(腰疼跟心悸也是那时候发生的)。你们看我的博客更新频率也能看出些,因为真是忙,忙到让我怀疑人生,非常累。这期间让我不想看书,不想游泳,也不想去更新博客(似乎找到了拖更的正当理由),只想周末的时候窝在沙发里。 现在回想,其实自己就是在逃避思考,光顾着战术勤奋,却不肯花时间,或者也可以说不懂去思考战略。 什么是战略呢?就是一个团队里面,不能所有人都埋头顾着眼前的事情,一定要有人看着前方的道路,**花时间解决重要而不紧急的问题,紧急不重要的事情少做,或者交给别人去做**。就如打游戏冲关一般,你不能光顾着打虾兵蟹将,不然只会被无穷无尽的它们给淹死,你的最终目标是打败 Boss 后通关,因此你需要在路上不断积累能够打 Boss 的资源与能力。因此如果你是一个团队在冲关时,一定有人要负责制定打 Boss 的计划,管好分工协作。 所以,**我在 2021 最大的收获就是真正入门管理**。 ### 管理 曾经觉得自己可以以一当十,所有事情不放心交给别人,都要自己干,累死自己(我要打十个变成被十个打),不懂何为「和光同尘」,终于在被提醒在为别人打工的时候,我才真正有所醒悟。 我学着从管理者的角度来思考: 1. 如何从自己的研发任务脱身出来,如何让公司跟团队能够活下去; 2. 如何调整研发队伍来适应公司业务发展的转向,如何规划团队的规模,以及人员构成,来提前为未来的业务发展提供保障; 3. 如何制定目标、建立流程、然后定义角色与职责,让每个人按部就班,用一个组织的能力来做个人不可能完成的事情;...
接着上次的简介(这个博主真会拖更 :P),我们来说说 MQTT 的一些基本概念。 ### 基本概念 在上次非常简单的 MQTT Hello World 中,我们其实就已经涉及到了一个非常重要的概念:发布与订阅。 想象大家很容易想起的,便是设计模式里面的发布订阅模式,确实,本质上 MQTT 实现的,就是架构上的发布订阅模式。 让我们回想下, 发布订阅模式的好处在哪里?解耦。如果说观察者模式是发送方与接收方的低耦合,那发布订阅模式是两方的完全解耦了。 ### 与消息队列的区别 而随后想起的便是各种分布式应用里面的各种消息队列中间件了(比如 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等),我们很容易理解错误的地方在于,认为他们两个是一类,但是它们应用的场景与范围完全不一样。 首先,需要明白的是 MQTT 只是一个应用层的协议,与之可以对比的是消息队列中的 AMQP 协议,MQTT Broker 则对应各种消息队列。 1. 云端的消息队列中间件通信协议更复杂,并且不需要考虑复杂的网络条件,但是...
又停更了,两个月。 🙈 我在上次的 [简介](https://github.com/xizhibei/blog/issues/179) 里简单提到过,如何用公共的 Broker 来做测试,显然,你不能用测试服务器当做生产环境的服务器,我们还是需要一个属于自己的服务器。 ### Mosquitto Mosquitto 可谓是开源届最有名气的 MQTT Broker 了,只是功能上勉强够用,有些如权限管理之类的高级功能需要自己安装插件,或者干脆自己的实现插件来拓展。 它还提供了一个公共的 Broker 可以用来测试: https://test.mosquitto.org/ 它的安装非常简单,直接安装相应的程序即可,比如在 Mac 中 `brew install mosquitto`,而在 Linux 中 `sudo api install mosquitto`。如果想用...
### 说在前面 最近两个月,我几乎是停更了,虽然之前提到过不会及时更新了,但是拖了那么久还是第一次。我当然可以用忙来解释,毕竟我周末用来刷 B 站的时间也少了好多。所以就陷入了另一个窘迫的地步:现在有素材可以写,但是这些可以拿来写的素材却是我忙起来之后才能得到,导致没有足够的精力时间去整理这些素材。 好了,话虽如此,博客还是要继续写的,不然积累的经验与知识又会不成体系。 是的,我又准备开个系列了,一方面,系列的文章会显得成体系一些,更能帮助一些刚刚入门的同学,另一方面,这样的话接下来不至于冥思苦想该写什么(好像这才是真实目的)。 ### MQTT 简介 MQTT 是非常简单的协议,最初由 IBM 的两位工程师 Andy Stanford-Clark 以及 Arlen Nipper 在 1999 年为监控输油管道设计的。它被设计的场景就是有限的带宽、轻量级以及很小的耗电量,在那个时候,卫星宽带就是那么小,且贵得让人肉疼。[1] 到了现代社会,虽然带宽的成本大大降低,但是仍有大量的场景需要用到这种协议,比如,智能家居(其实还是物联网)。许多的小型物联网设备靠着一块纽扣电池需要工作几年的时间,因此 MQTT 非常适合用来当作应用层的传输协议。 总结来说,MQTT 就是一个服务端、客户端架构的发布订阅消息传输协议。它非常轻量、开放、简单,设计上就非常容易实现。这些特性让它非常适合在如机器与机器(M2M)以及物联网(IoT) 这样受限于小内存以及窄带宽的领域发挥作用。[2] IBM 在...
这本书在我看来,就是在教你如何创业。因为,创业成功的难度不亚于一次火箭发射,虽然还会有更难的探月、探火星、载人,只是,这个过程中的方法论都是一致的,都是由普通的人类在用科学的方法,将不可能变为可能。 事实上,在技术行业,似乎做出一件伟大的产品似乎也是不可能的,比如你能在现在想象我们国家能在十年后造出可以跟 ASML 高端光刻机吗? 同样,可能你也无法在多年前想象我们国家有了自己的高铁、盾构机、003 航母、歼 20 战斗机,等等。 ### 将不可能变为可能 这本书的作者是是奥赞·瓦罗尔(Ozan Varol),一个前火箭科学家,美国俄勒冈州路易拉克大学法学院最年轻的终身教授。 整本书谈到的事情,其实就是如何将不可能变为可能。我们在工作中,肯定都会遇到当时认为不可能完成的事情,没有人会告诉你如何一步步去解决,如果这时候你能有书中告诉你的思维方式,你就完全有可能将不可能变为可能。首先就是绝不在一开始就承认不可能,起码需要去尝试,打破自己的固有认知,激发自己的创意,然后从一堆的创意材料中不断尝试、失败与总结,最终找出那个能点亮灯泡的钨丝。 对于创业的人来说,这种思维难能可贵,因为在他人看起来困难重重的事情,在你眼里却是充满机遇,你可以用火箭科学家的思维方式来打破不可能,重新定义现状,开辟新道路,打出一片江山来。 > 科学“不仅仅是知识,更是一种思维方式”。 其实在小时候,老师问我们想成为什么的时候,好多的同学说要成为科学家。我小时候也是这么想的,只不过我认为的科学家可能就是火箭科学家了,因为那时候刚从书本上知道了我们国家在 1970 年发射过东方红一号卫星。等我长大了,没有成为火箭科学家,更没有成为科学家,成为了一名计算机工程师(好吧,就是程序员)。 不过你看,其实这两者有相同之处:我们都在用科学的手段解决问题、实现梦想。 ### 自己的一些感悟与总结 接下来谈谈我从书中学到后,自己的几点感悟,涉及大量剧透。 #### 拥抱不确定性 我们的本能让我们对确定性非常迷恋,因为这是自然选择的结果:进化心理学也告诉我们那些追求不确定的人在远古时间往往难以生存,所以他们的基因无法传递给下一代。 但是当我们能克服这种倾向,敢于冒险,机遇才会向你招手。 > 只有当我们敢于牺牲确定性答案,敢于冒险,敢于远离路灯的时候,才能真正实现突破。 美国的阿波罗登月计划,是在没有完全的准备下才开始,事实上:...
今天来跟大家分享一个有趣的事情,在开始之前,想问问大家如何在 Git 中,如何在 Git 项目中,让一个文件消失?或者说,对 Git 来说不可见? 似乎很简单对不对?用 .gitignore 文件不就可以了。对,你说的没错,只是除了这个方法呢? ### 演示 接下来如果你如果想尝试这个方法,请别在你的真实项目中操作,搞坏了我可没法负责。 ```bash mkdir test_git_repo cd test_git_repo git init ``` 到这里没什么奇怪的对么,好,在 test_git_repo 这个目录里面继续。 ```bash mkdir hidden_path cd hidden_path git...
通常,我们只会在两种情况下,会去分析一个程序的表现: 1. 你遇到了问题; 2. 你闲的没事干; 好了,开个玩笑,其实研究程序的性能对于每一个工程师来说,都很重要,我甚至可以这么说:**这是一个工程师的必备技能**。 下面来说说,我们如何去研究 Golang 程序的性能问题。 ### 介绍 之前我也在 [穷人的程序性能分析器](https://github.com/xizhibei/blog/issues/158) 介绍过 C++ 的性能分析,以及很久之前也介绍过 [Node.js 性能分析之火焰图](https://github.com/xizhibei/blog/issues/57) ,那么今天就轮到 Golang 了。 相比之下,Golang 的性能分析工具 `pprof` 可谓是豪华了,它内建支持以下几种分析: * heap:当前内存中所有存活对象的采样(几乎是带 GC 语言的必备了),可以用来分析内存问题; *...
今天这篇文章算是对 [【CMake 系列】(五)安装、打包与导出](https://github.com/xizhibei/blog/issues/137) 的一个补充。其实我本打算跟上篇文章放在一起,毕竟都属于动态链接库相关的知识,但是这样一来就不容易被出现问题的同学们检索到了(才不是为了再水一篇文章 doge)。 ### 问题的由来 是因为这个问题困扰了我不少时间,在好几个项目里面都遇到了这个问题。 那就是链接动态库的时候,编译出来的可执行文件会带有编译时的绝对路径,于是你将程序拷贝到其它地方运行的时候,必须把动态库放到绝对路径里面去,而不是放在系统里面相关的 lib 路径下面。 举一个例子,假如我们要实现一个 `FooConfig.cmake`,这个库中既有静态库也有动态库,那么如果我们要在项目中使用,大概的实现方式是: ```cmake find_path(FOO_INCLUDE_DIRS NAMES foo.h) get_filename_component(_IMPORT_PREFIX "${FOO_INCLUDE_DIRS}" PATH) set(FOO_LIBRARY_DIRS ${_IMPORT_PREFIX}/lib) if(NOT FOO_FIND_COMPONENTS) set(FOO_FIND_COMPONENTS foo bar) endif() set(FOO_USE_SHARED 1)...
今天来说说,CMake 中稍许有些难度的部分:交叉编译。 虽说交叉编译有些难度,但是相对于其它的工具,CMake 的交叉编译支持还是很强大的,用一个 `CMAKE_TOOLCHAIN_FILE` 文件参数来制定交叉编译工具链就能解决大部分问题了。 ### 例子 下面来说说一个例子,比如我们现在需要编译 `aarch64`(即 ARM architecture 64位)上的可执行程序,或者库,我们就需要类似以下的工具链配置: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) # 交叉编译器 set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) # 设置搜索规则,这里需要重点注意,因为交叉编译所需要的依赖 # 一般不会放在系统目录下,而是会有专门的路径 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)...