HarmonyNext使用TcpSocket实现长连接(二) 原创

zhouchy
发布于 2025-3-8 21:49
浏览
0收藏

文章目录


概要

在上篇文章中,我们已经对整体架构有了初步的了解,这篇文章中,我将结合具体的使用场景,来对架构细节进行讲解。

技术名词解释

  • 报文:为了减小每次网络通信所占用的流量,通常通过自定义网络报文格式的方式来减小数据包的体积。报文的格式通常为 报文头+报文体。
  • 粘包/拆包:当数据包比较小时,有时会遇到接收到的数据包为多个报文拼在一起的情况,这种情况就是粘包;当数据包比较大时,有时又会遇到接收到的数据包不是一个完整的报文的情况,这种情况就是拆包。粘包、拆包在数据传输时是不可避免的,因此对于这两种情况的处理尤为重要,否则会影响数据的接收和解析。

技术细节

1、数据的发送与接收都是通过TCPSocket来实现的,在接收到服务器返回的数据时,将数据发送给Worker,在Worker中缓存接收到的字节数组,并在每次收到新数据后都解析一次报文头,得到完整报文的长度,并对以下情况分别进行处理:

1)缓存数据长度等于完整报文长度,则截取出完整报文,并发送给Task解析报文体。

2)缓存数据长度大于完整报文长度,则截取出完整报文,并发送给Task解析报文体。使用剩余的缓存数据解析报文头,并重复此步骤。

3)缓存数据长度小于完整报文长度,则等待接收新数据。

2、由于对服务器返回的数据进行处理时,会发生大量的运算操作,如果在UI线程中执行的话,会很容易造成ANR,因此我们需要在子线程中来处理。

官方给出子线程的实现方式有两种,一种是通过创建Task来执行耗时任务,另一种是通过创建Worker来实现。这两种方式的区别在于,Task的方式类似于线程池的概念,任务执行完会释放Task,并且多个Task可以并行执行。而Worker类似于单一线程,创建之后如果不手动释放,会一直存在。在我们的使用场景中会涉及到数据缓存和数据解析,下面我将分别针对这两项功能分析对比,采用哪种线程实现方式:

1)数据缓存:由于我们的使用场景中,在接收到服务器返回的数据时,需要处理粘包/拆包的问题,因此需要保证缓存数据的操作始终是在同一个线程中进行,基于上面的分析,Worker更加适合我们做数据的缓存操作。

2)数据解析:我们在Worker中实现了数据的缓存,在接收到完整的数据包时,就需要对完整的数据包进行解析,并且解析操作不应该阻碍继续接收和缓存数据,因此数据解析更适合使用Task来实现。

小结

本章节结合具体的使用场景,对架构细节进行讲解。下一章节我将提供一些样例代码供大家参考。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐