【六六互联】长期出售【美国抗投诉服务器】【欧洲抗投诉服务器】【亚洲抗投诉服务器】

数据包主线程收包后投递到逻辑处理线程

数据包经主线程收包后投递到逻辑处理线程

我们利用Linux reuseaddr和connect以后的udp fd特性,只有第一个数据包主线程收包后投递到逻辑处理线程,其它数据包直接在逻辑线程接收。

我们具体是怎么做的?

首先主线程还是创建一个fd,绑定7000端口。当然这里面有一个关键点是需要设置套接字的选项——reuseaddr,这个套接字选项在TCP领域用的很多,在UDP领域中大家可能还比较少接触。同样在主线监听可读事件。主线程开始收包了,同样的流程,收到到第一个stun包,获取WebRTC的web address(IP+端口)以及区分会议的RoomID和区分与会者的UserID。使用Hash(RoomID)到一个逻辑处理的子线程,到此为止流程与之前的多线程方案没有太大区别。

在逻辑处理子线程里面的方案就有一定的技巧了。它首先会在这个子线程里面再创建一个fd,这个fd监听的端口和主线程是一样的,也是7000端口。因为它设置了reuseaddr,所以说它的绑定可以成功,也就是说这个7000端口可以在多个线程里面同时监听。

接下来的流程就比较重要了,我们有了这个fd之后,我们需要做一次connect, connect在UDP领域大家使用得不多,但是它connect之后有什么效果呢?

大家可以阅读《UNIX网络编程 卷1第3版》的8.11,简单概括:UDP fd connect之后,会绑定本端与对端的四元组。当内核选择fd来收udp包时采用的是最佳匹配的原则。

因此connect过后的fd是四元组匹配最高的,这时内核会直接选择我们在子线程里面创建的fd。这个方案有点绕,但是还是比较有意思的,涉及到一些内核的事情,推荐大家感兴趣可以深入研究一下。在逻辑处理子线程中,我们还是会把这个新创建的fd注册到我们的事件循环里面。此后这个用户的上下行数据的IO操作将直接在这个逻辑处理线程。

数据包经主线程收包后投递到逻辑处理线程

这个方案就是我们优化后的Server的线程方案,它可以最大程度的降低跨线程的调用与加锁,整体的性能和代码的可读性也都会变高。