本文由微信开发团队工程师“virwu”分享。
1、引言
近期,微信小游戏反对了视频号一键开播,将微信降级到最新版本,关上腾讯系小游戏(如跳一跳、欢畅斗地主等),在右上角菜单就能够看到发动直播的按钮一键成为游戏主播了(如下图所示)。
然而微信小游戏出于性能和平安等一系列思考,运行在一个独立的过程中,在该环境中不会初始化视频号直播相干的模块。这就意味着小游戏的音视频数据必须跨过程传输到主过程进行推流,给咱们实现小游戏直播带来了一系列挑战。
(本文同步公布于:http://www.52im.net/thread-35...)
2、系列文章
本文是系列文章中的第5篇:
《直播零碎聊天技术(一):百万在线的美拍直播弹幕零碎的实时推送技术实际之路》
《直播零碎聊天技术(二):阿里电商IM音讯平台,在群聊、直播场景下的技术实际》
《直播零碎聊天技术(三):微信直播聊天室单房间1500万在线的音讯架构演进之路》
《直播零碎聊天技术(四):百度直播的海量用户实时音讯零碎架构演进实际》
《直播零碎聊天技术(五):微信小游戏直播在Android端的跨过程渲染推流实际》(* 本文)
3、视频采集推流
3.1 录屏采集?
小游戏直播实质上就是把主播手机屏幕上的内容展现给观众,自然而然地咱们能够想到采纳零碎的录屏接口MediaProjection进行视频数据的采集。
这种计划有这些长处:
1)零碎接口,实现简略,兼容性和稳定性有肯定保障;
2)前期能够扩大成通用的录屏直播;
3)对游戏性能影响较小,经测试对帧率影响在10%以内;
4)能够间接在主过程进行数据处理及推流,不必解决小游戏跨过程的问题。
然而最终这个计划被否决了,次要出于以下思考:
1)须要展现零碎受权弹窗;
2)须要审慎解决切出小游戏后暂停画面推流的状况,否则可能录制到主播的其余界面,有隐衷危险;
3)最要害的一点:产品设计上须要在小游戏上展现一个评论挂件(如下图),便于主播查看直播评论以及进行互动,录屏直播会让观众也看到这个组件,影响观看体验的同时会裸露一些只有主播能力看到的数据。
转念一想,既然小游戏的渲染齐全是由咱们管制的,为了更好的直播体验,是否将小游戏渲染的内容跨过程传输到主过程来进行推流呢?
3.2 小游戏渲染架构
为了更好地形容咱们采纳的计划,这里先简略介绍一下小游戏的渲染架构:
能够看到图中左半边示意在前台的小游戏过程,其中MagicBrush为小游戏渲染引擎,它接管来自于小游戏代码的渲染指令调用,将画面渲染到在屏的SurfaceView提供的Surface上。整个过程主过程在后盾不参加。
3.3 小游戏录屏时的状况
小游戏之前反对过游戏内容的录制,和直播原理上相似,都须要获取以后小游戏的画面内容。
录屏启用时小游戏会切换到如下的模式进行渲染:
能够看到,MagicBrush的输入指标不再是在屏的SurfaceView,而是Renderer产生的一个SurfaceTexture。
这里先介绍一下Renderer的作用:
Renderer是一个独立的渲染模块,示意一个独立的GL环境,它能够创立SurfaceTexture作为输出,收到SurfaceTexture的onFrameAvailable回调后通过updateTexImage办法将图像数据转换为类型是GL_TEXTURE_EXTERNAL_OES的纹理参加后续的渲染过程,并能够将渲染后果输入到另一个Surface上。
上面逐渐对图中过程进行解释:
1)MagicBrush接管来自小游戏代码的渲染指令调用,将小游戏内容渲染到第一个Renderer所创立的SurfaceTexture上;
2)随后这个Renderer做了两件事件:
2.1)将失去的小游戏画面纹理再次渲染到了在屏的Surface上;
2.2)提供纹理ID给到第二个Renderer(这里两个Renderer通过共享GLContext来实现共享纹理)。
3)第二个Renderer将第一个Renderer提供的纹理渲染到mp4编码器提供的输出SurfaceTexture上,最终编码器编码产生mp4录屏文件。
3.4 革新录屏计划?
能够看到,录屏计划中通过一个Renderer负责将游戏内容上屏,另一个Renderer将同样的纹理渲染到编码器上的形式实现了录制游戏内容,直播其实相似,是不是只有将编码器替换为直播的推流模块就能够了呢?
的确如此,但还短少要害的一环:推流模块运行在主过程,咱们须要实现跨过程传输图像数据!如何跨过程呢?
说到跨过程:可能咱们脑海里蹦出的第一反馈就是Binder、Socket、共享内存等等传统的IPC通信办法。但认真一想,零碎提供的SurfaceView是十分非凡的一个View组件,它不通过传统的View树来参加绘制,而是间接经由零碎的SurfaceFlinger来合成到屏幕上,而SurfaceFlinger运行在零碎过程上,咱们绘制在SurfaceView所提供的Surface上的内容必然是能够跨过程进行传输的,而Surface跨过程的办法很简略——它自身就实现了Parcelable接口,这意味着咱们能够用Binder间接跨过程传输Surface对象。
于是咱们有了上面这个初步计划:
能够看到:第3步不再是渲染到mp4编码器上,而是渲染到主过程跨过程传输过去的Surface上,主过程的这个Surface是通过一个Renderer创立的SurfaceTexture包装而来的,当初小游戏过程作为生产者向这个Surface渲染画面。当一帧渲染结束后,主过程的SurfaceTexture就会收到onFrameAvailable回调告诉图像数据曾经筹备结束,随之通过updateTexImage获取到对应的纹理数据,这里因为直播推流模块只反对GL_TEXTURE_2D类型的纹理,这里主过程Renderer会将GL_TEXTURE_EXTERNAL_OES转换为GL_TEXTURE_2D纹理后给到直播推流编码器,实现推流过程。
通过一番革新:上述计划胜利地实现了将小游戏渲染在屏幕上的同时传递给主过程进行推流,但这真的是最优的计划吗?
思考一番,发现上述计划中的Renderer过多了,小游戏过程中存在两个,一个用于渲染上屏,一个用于渲染到跨过程而来的Surface上,主过程中还存在一个用于转换纹理以及调用推流模块。如果要同时反对录屏,还须要在小游戏过程再起一个Renderer用于渲染到mp4编码器,过多的Renderer意味着过多的额定渲染开销,会影响小游戏运行性能。
3.5 跨过程渲染计划
纵观整个流程,其实只有主过程的Renderer是必要的,小游戏所应用的额定Render无非就是想同时满足渲染上屏和跨过程传输,让咱们大开脑洞——既然Surface自身就不受过程的束缚,那咱们罗唆把小游戏过程的在屏Surface传递到主过程进行渲染上屏吧!
最终咱们大刀阔斧地砍掉了小游戏过程的两个冗余Renderer,MagicBrush间接渲染到了跨过程传递而来的Surface上,而主过程的Renderer在负责纹理类型转换的同时也负责将纹理渲染到跨过程传递而来的小游戏过程的在屏Surface上,实现画面的渲染上屏。
最终所须要的Renderer数量从原来的3个缩小到了必要的1个,在架构更加清晰的同时晋升了性能。
后续须要同时反对录屏时,只有稍作改变,将mp4编码器的输出SurfaceTexture也跨过程传递到主过程,再新增一个Renderer渲染纹理到它下面就行了(如下图所示)。
3.6 兼容性与性能
到这里,不禁有点放心,跨过程传输和渲染Surface的这套计划的兼容性会不会有问题呢?
实际上,尽管并不常见,然而官网文档外面是有阐明能够跨过程进行绘制的:
SurfaceView combines a surface and a view. SurfaceView's view components are composited by SurfaceFlinger (and not the app), enabling rendering from a separate thread/process and isolation from app UI rendering.
并且Chrome以及Android O当前的零碎WebView都有应用跨过程渲染的计划。
在咱们的兼容性测试中,笼罩了Android 5.1及当前的各个支流零碎版本和机型,除了Android 5.x机型上呈现了跨过程渲染黑屏的问题外,其余均能够失常渲染上屏和推流。
性能方面:咱们应用了WebGL水族馆的Demo进行了性能测试,能够看到对于均匀帧率的影响在15%左右,主过程的CPU因为渲染和推流有所升高,奇怪的是小游戏过程的CPU开销却呈现了一些降落,这里降落的起因临时还没有确认,狐疑与上屏操作移到主过程相干,也不排除是统计办法的影响。
3.7 小结一下
为了实现不录制主播端的评论挂件,咱们从小游戏渲染流程动手,借助于Surface跨过程渲染和传输图像的能力,把小游戏渲染上屏的过程移到了主过程,并同时生成纹理进行推流,在兼容性和性能上达到了要求。
4、音频采集推流
4.1 计划抉择
在音频采集计划中,咱们留神到在Android 10及以上零碎提供了AudioPlaybackCapture计划容许咱们在肯定的限度内对系统音频进行采集。过后预研的一些论断如下。
捕捉方 - 进行捕捉的条件:
1)Android 10(api 29)及以上;
2)获取了RECORD_AUDIO权限;
3)通过MediaProjectionManager.createScreenCaptureIntent()进行MediaProjection权限的申请(和MediaProjection录屏共用);
4)通过AudioPlaybackCaptureConfiguration.addMatchingUsage()/AudioPlaybackCaptureConfiguration.excludeUsage() 增加/排除要捕捉的MEDIA类型;
5)通过 AudioPlaybackCaptureConfiguration.addMatchingUid() /AudioPlaybackCaptureConfiguration.excludeUid()增加/排除能够捕捉的利用的UID。
被捕捉方 - 能够被捕捉的条件:
1)Player的AudioAttributes设置的Usage为USAGE_UNKNOWN,USAGE_GAME或USAGE_MEDIA(目前绝大部分用的都是默认值,能够被捕捉);
2)利用的CapturePolicy被设置为AudioAttributes#ALLOW_CAPTURE_BY_ALL,有三种方法能够设置(以最严格的为准,目前微信内没有配置,默认为能够捕捉);
3)通过manifest.xml设置android:allowAudioPlaybackCapture="true",其中,TargetApi为29及以上的利用默认为true,否则为false;
4)api 29及以上能够通过setAllowedCapturePolicy办法运行时设置;
5)api 29及以上能够通过AudioAttributes针对每一个Player独自设置。
总的来说:Android 10及以上能够应用AudioPlaybackCapture计划进行音频捕捉,但思考到Android 10这个零碎版本限度过高,最终咱们抉择了本人来采集并混合小游戏内播放的所有音频。
4.2 跨过程音频数据传输
当初,老问题又摆在了咱们眼前:小游戏混合后的音频数据在小游戏过程,而咱们须要把数据传输到主过程进行推流。
与个别的IPC跨过程通信用于办法调用不同:在这个场景下,咱们须要频繁地(40毫秒一次)传输较大的数据块(16毫秒内的数据量在8k左右)。
同时:因为直播的个性,这个跨过程传输过程的提早须要尽可能地低,否则就会呈现音画不同步的状况。
为了达到上述指标:咱们对Binder、LocalSocket、MMKV、SharedMemory、Pipe这几种IPC计划进行了测试。在搭建的测试环境中,咱们在小游戏过程模仿实在的音频传输的过程,每隔16毫秒发送一次序列化后的数据对象,数据对象大小分为3k/4M/10M三挡,在发送前贮存工夫戳在对象中;在主过程中接管到数据并实现反序列化为数据对象的时刻作为完结工夫,计算传输提早。
最终失去了如下后果:
注:其中XIPCInvoker(Binder)和MMKV在传输较大数据量时耗时过长,不在后果中展现。
对于各个计划的剖析如下(卡顿率示意提早>2倍均匀提早且>10毫秒的数据占总数的比例):
能够看到:LocalSocket计划在各个状况下的传输提早体现都极为优异。差别的起因次要是因为裸二进制数据在跨过程传输到主过程后,仍须要进行一次数据拷贝操作来反序列化为数据对象,而应用LocalSocket时能够借助于ObjectStream和Serializeable来实现流式的拷贝,相比与其余计划的一次性接收数据后再拷贝节约了大量的工夫(当然其余计划也能够设计成分块流式传输同时拷贝,但实现起来有肯定老本,不如ObjectStream稳固易用)。
咱们也对LocalSocket进行了兼容性与性能测试,未呈现不能传输或断开连接的状况,仅在三星S6上均匀提早超过了10毫秒,其余机型提早均在1毫秒左右,能够满足咱们的预期。
4.3 LocalSocket的安全性
罕用的Binder的跨过程安全性有零碎实现的鉴权机制来保障,LocalSocket作为Unix domain socket的封装,咱们必须思考它的安全性问题。
论文《The Misuse of Android Unix Domain Sockets and Security Implications》较为具体地剖析了Android中应用LocalSocket所带来的平安危险。
PS:论文原文附件下载(请从此链接的4.3节处下载:http://www.52im.net/thread-35...)
总结论文所述:因为LocalSocket自身不足鉴权机制,任意一个利用都能够进行连贯,从而截取到数据或是向接收端传递非法数据引发异样。
针对这个特点,咱们能够做的进攻办法有两种:
1)随机化LocalSocket的命名,例如应用以后直播的小游戏的AppId和用户uin等信息计算md5作为LocalSocket的名字,使得攻击者无奈通过固定或穷举名字的办法尝试建设连贯;
2)引入鉴权机制,在连贯胜利后发送特定的随机信息来验证对方的真实性,而后才启动真正的数据传输。
4.4 小结一下
为了兼容Android 10以下的机型也能直播,咱们抉择本人解决小游戏音频的采集,并通过比照评测,选用了LocalSocket作为跨过程音频数据传输的计划,在提早上满足了直播的需要。
同时,通过一些反抗措施,能够无效躲避LocalSocket的平安危险。
5、多过程带来的问题
回头来看,尽管整个计划看起来比拟通顺,然而在实现的过程中还是因为多过程的起因踩过不少坑,上面就分享其中两个比拟次要的。
5.1 glFinish造成渲染推流帧率重大降落
在刚实现跨过程渲染推流的计划后,咱们进行了一轮性能与兼容性测试,在测试中发现,局部中低端机型上帧率降落十分重大(如下图所示)。
复现后查看小游戏过程渲染的帧率(即小游戏过程绘制到跨过程而来的Surface上的帧率)发现能够达到不开直播时的帧率。
而咱们所用的测试软件PerfDog所记录的是在屏Surface的绘制帧率,这就阐明性能降落不是直播开销过高引起的小游戏代码执行效率降落,而是主过程上屏Renderer效率太低。
于是咱们对主过程直播时运行效率进行了Profile,发现耗时函数为glFinish。
并且有两次调用:
1)第一次调用是Renderer将内部纹理转2D纹理时,耗时会达到100多毫秒;
2)第二次调用是腾讯云直播SDK外部,耗时10毫秒以内。
如果将第一次调用去掉,直播SDK外部的这次则会耗时100多毫秒。
为了弄清为什么这个GL指令耗时这么久,咱们先看看它的形容:
glFinish does not return until the effects of all previously called GL commands are complete.
形容很简略:它会阻塞直到之前调用的所有GL指令全副实现。
这么看来是之前的GL指令太多了?然而GL指令队列是以线程为维度隔离的,在主过程的Renderer线程中,glFinish前只会执行纹理类型转换的十分大量的GL指令,和腾讯云的同学理解到推流接口也不会在本线程执行很多GL指令,如此大量的GL指令怎么会使glFinish阻塞这么久呢?等等,大量GL指令?小游戏过程此时不就正在执行大量GL指令吗,难道是小游戏过程的大量GL指令导致了主过程的glFinsih耗时过长?
这样的猜想不无道理:尽管GL指令队列是按线程隔离的,但解决指令的GPU只有一个,一个过程的GL指令过多导致另一个过程在须要glFinish时阻塞过久。Google了一圈没找到有相干的形容,须要本人验证这个猜想。
从新察看一遍下面的测试数据:发现直播前能达到60帧的状况下,直播后也能达到60帧左右,这是不是就阐明在小游戏的GPU负载较低时glFinish的耗时也会降落呢?
在性能降落重大的机型上:管制其余变量不变尝试运行低负载的小游戏,发现glFinsih的耗时胜利降落到了10毫秒左右,这就印证了下面的猜想——的确是小游戏过程正在执行的大量GL指令阻塞了主过程glFinish的执行。
该如何解决呢?小游戏过程的高负载无奈扭转,那能让小游戏在一帧渲染实现当前停住等主过程的glFinish实现后再渲染下一帧吗?
这里通过了各种尝试:OpenGL的glFence同步机制无奈跨过程应用;因为GL指令是异步执行的,通过跨过程通信加锁锁住小游戏的GL线程并不能保障主过程执行glFinish时小游戏过程的指令曾经执行完,而能保障这点只有通过给小游戏过程加上glFinish,但这会使得双缓冲机制生效,导致小游戏渲染帧率的大幅降落。
既然glFinish所带来的阻塞无奈防止,那咱们回到问题的开始:为什么须要glFinish?因为双缓冲机制的存在,一般来说并不需要glFinish来期待之前的绘制实现,否则双缓冲就失去了意义。两次glFinish中,第一次纹理解决的调用能够间接去掉,第二次腾讯云SDK的调用通过沟通,发现是为了解决一个历史问题引入的,能够尝试去掉。在腾讯云同学的帮忙下,去掉glFinish后,渲染的帧率终于和小游戏输入的帧率统一,通过兼容性和性能测试,没有发现去掉glFinish带来的问题。
这个问题最终的解法很简略:但剖析问题起因的过程实际上做了十分多的试验,同一个利用中一个高GPU负载的过程会影响到另一个过程的glFinish耗时的这种场景的确也十分少见,能参考的材料不多。这个过程也让我粗浅领会到了glFinish使得双缓冲机制生效所带来的性能影响是微小的,在应用OpenGL进行渲染绘制时对于glFinish的应用该当十分审慎。
5.2 后盾过程优先级问题
在测试过程中:咱们发现无论以多少的帧率向直播SDK发送画面,观众端看到的画面帧率始终只有16帧左右,排除后盾起因后,发现是编码器编码的帧率有余导致的。经腾讯云同学测试同过程内编码的帧率是能够达到设定的30帧的,那么阐明还是多过程带来的问题,这里编码是一个十分重的操作,须要耗费比拟多的CPU资源,所以咱们首先狐疑的就是后盾过程优先级的问题。
为了确认问题:
1)咱们找来了曾经root的手机,通过chrt命令进步编码线程的优先级,观众端帧率立马上到了25帧;
2)另一方面,经测试如果在小游戏过程上显示一个主过程的浮窗(使主过程具备前台优先级),帧率能够上到30帧。
综上:能够确认帧率降落就是因为后盾过程(以及其领有的线程)的优先级过低导致的。
进步线程优先级的做法在微信里比拟常见,例如:小程序的JS线程以及小游戏的渲染线程都会在运行时通过android.os.Process.setThreadPriority办法设置线程的优先级。腾讯云SDK的同学很快提供了接口供咱们设置线程优先级,但当咱们真正运行起来时,却发现编码的帧率仅从16帧进步到了18帧左右,是哪里出问题了呢?
后面提到:咱们通过chrt命令设置线程优先级是无效的,但android.os.Process.setThreadPriority这个办法设置的线程优先级对应的是renice这个命令设置的nice值。仔细阅读chrt的manual后,发现之前测试时的了解有误,之前间接用chrt -p [pid] [priority]的命令设置优先级,却没有设置调度策略这个参数,导致该线程的调度策略从Linux默认的SCHED_OTHER改为了命令缺省设置的SCHED_RR,而SCHED_RR是一种“实时策略”,导致线程的调度优先级变得十分高。
实际上:通过renice(也就是android.os.Process.setThreadPriority)设置的线程优先级,对于后盾过程所领有线程来说没有太大的帮忙。
其实早有人解释过这一点:
To address this, Android also uses Linux cgroups in a simple way to create more strict foreground vs. background scheduling. The foreground/default cgroup allows thread scheduling as normal. The background cgroup however applies a limit of only some small percent of the total CPU time being available to all threads in that cgroup. Thus if that percentage is 5% and you have 10 background threads all wanting to run and one foreground thread, the 10 background threads together can only take at most 5% of the available CPU cycles from the foreground. (Of course if no foreground thread wants to run, the background threads can use all of the available CPU cycles.)
对于线程优先级的设置,感兴趣的同学能够看看另一位大佬的文章:《Android的离奇陷阱 — 设置线程优先级导致的微信卡顿惨案》。
最终:为了进步编码帧率并避免后盾主过程被杀,咱们最终还是决定直播时在主过程创立一个前台Service。
6、总结与瞻望
多过程是一把双刃剑,在给咱们带来隔离性和性能劣势的同时也带来了跨过程通信这一难题,所幸借助零碎Surface的能力和多种多样的跨过程计划能够较好地解决小游戏直播中所遇到的问题。
当然:解决跨过程问题最好的计划是防止跨过程,咱们也思考了将视频号直播的推流模块运行在小游戏过程的计划,但出于革新老本的思考而没有抉择这一计划。
同时:这次对于SurfaceView跨过程渲染的实际也对其余业务有肯定参考价值——对于一些内存压力较大或是平安危险较高,又须要进行SurfaceView渲染绘制的场景,能够把逻辑放到独立的过程,再通过跨过程渲染的形式绘制到主过程的View上,在取得独立过程劣势的同时又防止了过程间跳转所带来的体验的割裂。
附录1:无关直播技术的文章汇总
《挪动端实时音视频直播技术详解(一):开篇》
《挪动端实时音视频直播技术详解(二):采集》
《挪动端实时音视频直播技术详解(三):解决》
《挪动端实时音视频直播技术详解(四):编码和封装》
《挪动端实时音视频直播技术详解(五):推流和传输》
《挪动端实时音视频直播技术详解(六):提早优化》
《实践联系实际:实现一个简略地基于html]5的实时视频直播》
《实时视频直播客户端技术盘点:Native、html]5、WebRTC、微信小程序》
《Android直播入门实际:入手搭建一套简略的直播零碎》
《淘宝直播技术干货:高清、低延时的实时视频直播技术解密》
《技术干货:实时视频直播首屏耗时400ms内的优化实际》
《新浪微博技术分享:微博实时直播答题的百万高并发架构实际》
《实时音频的混音在视频直播中的技术原理和实际总结》
《七牛云技术分享:应用QUIC协定实现实时视频直播0卡顿!》
《近期大热的实时直播答题零碎的实现思路与技术难点分享》
《P2P技术如何将实时视频直播带宽升高75%?》
《网易云信实时视频直播在TCP数据传输层的一些优化思路》
《首次披露:快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?》
《浅谈实时音视频直播中间接影响用户体验的几项要害技术指标》
《技术揭秘:反对百万级粉丝互动的Facebook实时视频直播》
《挪动端实时视频直播技术实际:如何做到实时秒开、晦涩不卡》
《实现提早低于500毫秒的1080P实时音视频直播的实际分享》
《浅谈开实时视频直播平台的技术要点》
《直播零碎聊天技术(一):百万在线的美拍直播弹幕零碎的实时推送技术实际之路》
《直播系聊天技术(二)阿里电商IM音讯平台,在群聊、直播场景下的技术实际》
《直播零碎聊天技术(三):微信直播聊天室单房间1500万在线的音讯架构演进之路》
《直播零碎聊天技术(四):百度直播的海量用户实时音讯零碎架构演进实际》
《直播零碎聊天技术(五):微信小游戏直播在Android端的跨过程渲染推流实际》
《海量实时音讯的视频直播零碎架构演进之路(视频+PPT)[附件下载]》
《YY直播在挪动弱网环境下的深度优化实际分享(视频+PPT)[附件下载]》
《从0到1:万人在线的实时音视频直播技术实际分享(视频+PPT) [附件下载]》
《在线音视频直播室服务端架构最佳实际(视频+PPT) [附件下载]》
更多同类文章 ……
附录2:微信团队分享的技术文章汇总
《微信朋友圈千亿访问量背地的技术挑战和实际总结》
《微信团队分享:微信挪动端的全文检索多音字问题解决方案》
《微信团队分享:iOS版微信的高性能通用key-value组件技术实际》
《微信团队分享:iOS版微信是如何避免特殊字符导致的炸群、APP解体的?》
《微信团队原创分享:iOS版微信的内存监控零碎技术实际》
《iOS后盾唤醒实战:微信收款到账语音揭示技术总结》
微信团队分享:视频图像的超分辨率技术原理和利用场景》
《微信团队分享:微信每日亿次实时音视频聊天背地的技术解密》
《微信团队分享:微信Android版小视频编码填过的那些坑》
《微信手机端的本地数据全文检索优化之路》
《企业微信客户端中组织架构数据的同步更新计划优化实战》
《微信团队披露:微信界面卡死超级bug“15。。。。”的前因后果》
《月活8.89亿的超级IM微信是如何进行Android端兼容测试的》
《一篇文章get微信开源挪动端数据库组件WCDB的所有!》
《微信客户端团队负责人技术访谈:如何着手客户端性能监控和优化》
《微信后盾基于工夫序的海量数据冷热分级架构设计实际》
《微信团队原创分享:Android版微信的臃肿之困与模块化实际之路》
《微信后盾团队:微信后盾异步音讯队列的优化降级实际分享》
《微信团队原创分享:微信客户端SQLite数据库损坏修复实际》
《微信Mars:微信外部正在应用的网络层封装库,行将开源》
《如约而至:微信自用的挪动端IM网络层跨平台组件库Mars已正式开源》
《开源libo库:单机千万连贯、撑持微信8亿用户的后盾框架基石 [源码下载]》
《微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解》
《微信团队原创分享:Android版微信后盾保活实战分享(过程保活篇)》
《微信团队原创分享:Android版微信后盾保活实战分享(网络保活篇)》
《Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]》
《微信团队原创分享:Android版微信从300KB到30MB的技术演进》
《微信技术总监谈架构:微信之道——大道至简(演讲全文)》
《微信技术总监谈架构:微信之道——大道至简(PPT讲稿) [附件下载]》
《如何解读《微信技术总监谈架构:微信之道——大道至简》》
《微信海量用户背地的后盾零碎存储架构(视频+PPT) [附件下载]》
《微信异步化革新实际:8亿月活、单机千万连贯背地的后盾解决方案》
《微信朋友圈海量技术之道PPT [附件下载]》
《微信对网络影响的技术试验及剖析(论文全文)》
《一份微信后盾技术架构的总结性笔记》
《架构之道:3个程序员成就微信朋友圈日均10亿发布量[有视频]》
《疾速裂变:见证微信弱小后盾架构从0到1的演进历程(一)》
《疾速裂变:见证微信弱小后盾架构从0到1的演进历程(二)》
《微信团队原创分享:Android内存透露监控和优化技巧总结》
《全面总结iOS版微信降级iOS9遇到的各种“坑”》
《微信团队原创资源混同工具:让你的APK立减1M》
《微信团队原创Android资源混同工具:AndResGuard [有源码]》
《Android版微信安装包“减肥”实战记录》
《iOS版微信安装包“减肥”实战记录》
《挪动端IM实际:iOS版微信界面卡顿监测计划》
《微信“红包照片”背地的技术难题》
《挪动端IM实际:iOS版微信小视频性能技术计划实录》
《挪动端IM实际:Android版微信如何大幅晋升交互性能(一)》
《挪动端IM实际:Android版微信如何大幅晋升交互性能(二)》
《挪动端IM实际:实现Android版微信的智能心跳机制》
《挪动端IM实际:WhatsApp、Line、微信的心跳策略剖析》
《挪动端IM实际:谷歌音讯推送服务(GCM)钻研(来自微信)》
《挪动端IM实际:iOS版微信的多设施字体适配计划探讨》
《IPv6技术详解:基本概念、利用现状、技术实际(上篇)》
《IPv6技术详解:基本概念、利用现状、技术实际(下篇)》
《微信多媒体团队访谈:音视频开发的学习、微信的音视频技术和挑战等》
《腾讯技术分享:微信小程序音视频技术背地的故事》
《腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面》
《微信多媒体团队梁俊斌访谈:聊一聊我所理解的音视频技术》
《腾讯音视频实验室:应用AI黑科技实现超低码率的高清实时视频聊天》
《腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实际》
《手把手教你读取Android版微信和手Q的聊天记录(仅作技术钻研学习)》
《微信技术分享:微信的海量IM聊天音讯序列号生成实际(算法原理篇)》
《微信技术分享:微信的海量IM聊天音讯序列号生成实际(容灾计划篇)》
《腾讯技术分享:GIF动图技术详解及手机QQ动静表情压缩技术实际》
《微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅》
《社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进》
《社交软件红包技术解密(三):微信摇一摇红包雨背地的技术细节》
《社交软件红包技术解密(四):微信红包零碎是如何应答高并发的》
《社交软件红包技术解密(五):微信红包零碎是如何实现高可用性的》
《社交软件红包技术解密(六):微信红包零碎的存储层架构演进实际》
《社交软件红包技术解密(十一):解密微信红包随机算法(含代码实现)》
《微信团队分享:极致优化,iOS版微信编译速度3倍晋升的实际总结》
《IM“扫一扫”性能很好做?看看微信“扫一扫识物”的残缺技术实现》
《微信团队分享:微信领取代码重构带来的挪动端软件架构上的思考》
《IM开发宝典:史上最全,微信各种性能参数和逻辑规定材料汇总》
《微信团队分享:微信直播聊天室单房间1500万在线的音讯架构演进之路》
更多同类文章 ……
(本文同步公布于:http://www.52im.net/thread-35...)