热门标签 | HotTags
当前位置:  开发笔记 > 开放平台 > 正文

客户端架构设计的简单总结

我们知道,客户端是相对服务端而言的,客户端程序相对普通应用程序,主要是增加了网络通讯功能。在这个移动和云存储的年代,大部分终端应用程序都有网络通讯功能,所以都可以称为客户端。常见的


我们知道,客户端是相对服务端而言的,客户端程序相对普通应用程序,主要是增加了网络通讯功能。在这个移动和云存储的年代,大部分终端应用程序都有网络通讯功能, 所以都可以称为客户端。常见的客户端如浏览器,IM客户端, 网络会议客户端,邮件客户端,微博和微信客户端等...

通过观察,我们会发现所有的客户端基本是大同小异,都会包括一些相同的功能组件, 下面简单例举下:



通讯协议层


既然客户端都有网络功能,就会涉及到通讯方式和数据格式以及协议, 这三者不是完全独立,而是有机统一的。

首先说通讯方式,常见的通讯方式包括TCP,UDP, P2P和http(s), 很多时候我们不会用单一的通讯方式,而是多种通讯方式的结合。比如说TCP端口被封,走不通时,我们会转成尝试http(s)。IM中聊天文本走的是TCP, 由服务器转发,但是2个客户端之间的文件传输我们可能走的又是P2P了, 多个人之间的语音聊天, 我们走的又是UDP了。

其次说数据格式,常见的数据格式包括二进制编码,开源序列化协议和文本格式。
二进制一般是自定义的私有格式,通常对数值,我们会转成大头端,对字符串我们会用UTF8 编码,因为没有冗余数据,它的优点是不会浪费带宽;主要缺点是有硬编码的味道,不好扩充。
开源序列化协议这里主要是指google的protocal buffer,  现在很多公司都在用, 很多人基于它开发了自己的RPC框架。主要优点是数据小,使用简单而高效。
文本格式主要是指xml和json. 相对来说xml比较清晰和容易扩充,但是冗余数据比较多。json借助Javascript对它语言层次的支持,感觉主要是前端人员使用的比较多。

最后再说协议,  协议和我们的应用相关联。比如邮件客户端,当然是走SMTP和POP3了; IM客户端的话,一般走XMPP了;  网络会议的话,可以走ITU的T.120协议, 也可以RFC 6501定义的XCON, 信令走SIP, 数据走RTP等。

通信协议层是整个客户端网络事件驱动的引擎,它可能会比较简单,也可能会很复杂。如果是基于XMPP的IM, 它可能会比较简单,因为基本上只需要一层文本协议的封包和解包就可以了。 当如果是基于T.120网络会议客户端,就会比较复杂,它数据包走的自定义的二机制格式,按照T.120协议的建议, 在通讯协议层又分了3层:TP, MCS和GCC。TP层主要封装数据传输的方式, 可以让上层无差别的区分TCP和http(s)。 MCS层主要提供多点传输功能, 它抽象出通道(channel)这个概念, 让不同session的数据进行逻辑隔离, 上层用户可以同时加入不同的通道来进行一对一和一对多的数据收发,并且通道中的数据有不同的优先级, 还有令牌这个机制。我们也可以在MCS层对数据进行加密和压缩, 还可以对上层的大数据包进行切包等。 GCC层主要封装会议的最基本逻辑,比如创建会议和加入session数据包的格式封装等, 让上层可以通过API调用而不用关心协议要求的数据包格式。不同的数据包会工作在不同的层次, 比如心跳包可能在底层TP层就被拦截了,它不要再往上层发,因为上面不用关心这个; 而有些数据包,则需要从底层往上层按照整个协议栈层层转发,当然每层都会剥离掉自己的协议头, 直至上层用户数据到达它的最终用户。

总之,通讯协议层封装了客户端和服务端的通讯方式及协议格式, 让上层用户不用关心底层的通信机制, 而只关注应用的接口事件。理论上我们可以在上层应用不做大调整的前提下,直接将网络会议客户端中的T.120协议成基于SIP的XCON。



功能组件


一个客户端程序通常是由很多功能模块组成,模块按功能来说可以分为基础组件和应用组件。

基础组件为应用组件提供的基础设施,基础组件是可以在不同的项目中重复使用的(比如界面控件库,2D渲染引擎Skia, 跨平台的网络和线程库等)。 
应用组件通常和我们当前的特定应用程序相关,比如我们的网络会议客户端包含的桌面共享模块, 文档共享模块,视频音频模块,文本聊天模块等。

应用模块本身分为带界面和无界面两种情况, 带界面的情况下我们通常会给组件提供一个容器窗口的句柄, 让组件自己在内部组织自己的界面。这种带界面的组件通常会为逻辑和界面的分离带来麻烦,在Window上实现一些半透明和动画效果也很难。 比如我们想提供跨平台的SDK来封装逻辑,这时我们会更倾向让应用组件采用无界面的模式,组件在跨平台层只封装逻辑和提供数据, 而把数据发到最上层界面层后再统一处理。

对功能组件我们的设计原则是尽量保持独立和可复用,最好能以仿COM方式动态升级而不用重新编译, 另外组件之间要保持层次性,避免双向或是循环依赖。



数据存储


客户端本身是处理和收发网络数据, 这里就涉及到对这些数据如何组织和存储的问题。这个通常会根据客户端的类型采用不同的处处理方式:
对于永久存储的数据,当然是保存成文件或是存入数据库,文件如xml, 数据库如ACCESS,  SQL server, mysql等。
临时数据当然是存入内存了,根据需要采用不同的数据结构, 组织格式如array,list, map, hashmap等。
还有一种是常见的数据保存方式是内存数据库,最常见是SQLite了, 内存数据库既能高效的分类保存大量数据, 又可以直接用基于SQL语句进行查询和处理, 比如foxmail客户端就是用SQLite存储的邮件信息。
还有一种是跨进程共享的数据,我们一般当然是内存映射文件了。比如我们有一个实时显示log的工具, 我们通常会在对方应用程序里分配共享内存的内存映射文件,所有的log都写到里面,然后在log工具程序里读取和显示。
当然还有一些数据可能存到网上去的, 常见的比如我们的云笔记, 这时数据分服务端数据和本地cache。

对于数据存储我们的设计原则是根据需要,选择简单高效的方式。比如我们在设计网络会议客户端时曾讨论要不要引入SQLite, 理想情况是引入内存数据库后各个组件和上层应用的数据都可以统一存储,采用数据驱动的方式,可以很方便的跟踪整个客户端的运行情况。但后来发现这种设计会把本来各自独立的组件通过数据库耦合在了一起,而且各组件的数据格式本身都很不要一样, 很难统一存储, 另外很多数据实际也只是临时数据, 没必要把简单的事情做复杂了。





客户端框架


客户端框架一般有两个作用:一是把所有的功能组件组织起来,进行统一的管理和展现; 二是实现整个客户端的主界面。客户端框架在协调各个组件时, 要注意避免让组件之间产生双向依赖, 而是应该让组件把事件通知给框架后由框架统一协调和处理, 所以客户端框架通常是整个客户端逻辑最复杂的部分。 一个好的客户端框架,通常会采用插件方式设计,可以动态插拔需要的组件。最好是可以根据服务端的配置, 动态下载和更新所需要的插件。

对于客户端框架, 我们的设计原则是低耦合和可扩展。基本上所有下层组件的改动都会影响到我们的客户端框架,客户的很多新需求和新组件也会导致框架产生坏味道, 这里我们设计时就要考虑如何让客户端框架能及时的适应这些变化。





界面库

客户端肯定会有界面,在Windows平台上,现在的界面大致分为以下几类:
基于Windows原始窗口控件句柄的C++ native 客户端, 基于.net的winform客户端,基于.net的WPF客户端,基于C++的DirectUI客户端, 以嵌入浏览器(如webkit)方式实现的客户端, 还有一类是基于Xaml的Metro客户端。

对于企业级大型安装应用,主要考虑的是开发效率,所以客户端还是以.net为主; 但是对于互联网企业, 更多的是要求客户端精简而高效, 所以还是以C++为主。 这里就设及到C++的两种界面库, 一种是基于windows窗口句柄和控件自绘机制的界面库,还有一中是基于DirectUI的界面库, 现在大一点的公司基本上都有自己的DirectUI界面库。基于修改Webkit方式实现的界面库可以通过Canvas和SVG动画等方式实现一些很炫的效果, 但是它和标准程序的用户体验还是有一定差距:一来web实现的控件跟Windows标准控件有很大不同, 二来web的流式布局和应用程序的网格布局也不一样。

对于界面,个人觉得这个东西变化实在太快了,所以我觉得应该尽量用界面和逻辑相分离的方式组织代码。



总结

对于客户端架构设计,个人觉得最大的原则就分层设计, 每层都封装一个概念并保持独立, 同时根据依赖倒置的原则, 站在上层客户的角度提供接口。软件工程里面的一条黄金定律:“任何问题都可以通过增加一个间接层来解决。









转载于:https://www.cnblogs.com/weiym/p/3870817.html



推荐阅读
  • 本文介绍了如何使用PHP代码实现微信平台的媒体素材上传功能,详细解释了API接口的使用方法和注意事项,确保文件路径正确以避免常见的错误。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • 从零开始构建完整手机站:Vue CLI 3 实战指南(第一部分)
    本系列教程将引导您使用 Vue CLI 3 构建一个功能齐全的移动应用。我们将深入探讨项目中涉及的每一个知识点,并确保这些内容与实际工作中的需求紧密结合。 ... [详细]
  • 阅读本文大约需要3分钟。微信8.0版本的发布带来了许多令人振奋的新功能,如烟花特效和改进的悬浮窗,引发了用户的热烈反响。 ... [详细]
  • 本文详细介绍如何在微信商户平台上下载支付操作证书,并将其正确配置到支付账户中。包括登录步骤、密码重置以及证书上传的具体操作。 ... [详细]
  • 微信历史头像查询指南:轻松找回旧头像
    您是否想查看之前使用过的微信头像?本文将详细介绍如何通过简单步骤找回您的历史头像。不仅如此,我们还会提供一些实用技巧和注意事项,帮助您更好地管理个人资料。 ... [详细]
  • 射频系统中IM3、IIP3、OIP3、增益和P1dB的关系解析
    本文探讨了噪声系数与非线性失真对射频系统性能的影响,详细分析了IM3、IIP3、OIP3、增益(G)和1dB压缩点(P1dB)之间的关系,并提供了相关公式和图表解释。 ... [详细]
  • 本文将深入探讨PHP编程语言的基本概念,并解释PHP概念股的含义。通过详细解析,帮助读者理解PHP在Web开发和股票市场中的重要性。 ... [详细]
  • 本文探讨了将类成员属性设置为私有的重要性,并通过具体代码示例展示了如何实现对这些属性的有效控制。私有成员属性有助于增强数据的安全性和完整性,确保只有经过验证的数据才能被修改。 ... [详细]
  • 易飞扬宣布推出新型低成本100G OTU4光模块,以满足DPI市场的需求。新产品包括100G CFP2 LR4 10KM和100G OTU4 QSFP28 LR4光模块,具备低功耗和高性能特点。 ... [详细]
  • 本文深入探讨了计算机网络的基础概念和关键协议,帮助初学者掌握网络编程的必备知识。从网络结构到分层模型,再到传输层协议和IP地址分类,文章全面覆盖了网络编程的核心内容。 ... [详细]
  • 在众多不为人知的软件中,这些工具凭借其卓越的功能和高效的性能脱颖而出。本文将为您详细介绍其中八款精品软件,帮助您提高工作效率。 ... [详细]
  • 深入解析TCP/IP五层协议
    本文详细介绍了TCP/IP五层协议模型,包括物理层、数据链路层、网络层、传输层和应用层。每层的功能及其相互关系将被逐一解释,帮助读者理解互联网通信的原理。此外,还特别讨论了UDP和TCP协议的特点以及三次握手、四次挥手的过程。 ... [详细]
  • 本文详细介绍了网络存储技术的基本概念、分类及应用场景。通过分析直连式存储(DAS)、网络附加存储(NAS)和存储区域网络(SAN)的特点,帮助读者理解不同存储方式的优势与局限性。 ... [详细]
  • 本文记录了作者在一次旅途中阅读阿道司·赫胥黎的《美丽新世界》的心得。通过探讨小说中对未来社会的预言,文章揭示了集权政府对人性和社会结构的潜在威胁,并反思了现代社会中的一些现象。 ... [详细]
author-avatar
心诚新城
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有