WEBIM-UI重构小结

本文总结了WEBIM-UI重构的过程,包括重构前的问题,如代码混乱、流程耦合等,以及如何通过整理指令流程、提取公共逻辑、引入组合指令和设计模式来改善这些问题。重构后采用管道-过滤器模式,提升了模块的灵活性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1          简介

UI 的全称是 User Interface ,但公司里的通用定义是:用于 web 类接入服务的后端接入模块,常用于用户身份校验、页面渲染和协议转换等功能,位置介于 web 服务器和逻辑服务器之间。在 Webim 系统结构中,由于前后端基于数据分离,即后端只是提供数据,由前端 js 完成页面渲染,因此 Webim 系统内的 UI 更多地承担了身份校验和协议转换的功能。

2          重构

2.1          重构之前

重构前 WEBIM-UI 主要存在的问题如下:

1.        代码庞大,组织较混乱,最大的一个源文件代码超过 1w 行。

2.        流程不够清晰,指令流程与具体实现耦合较紧,导致修改指令处理流程和新增指令较为困

难,特别是后期同时支持 bridge 和普通用户时这一点尤为突出。

3.        公共逻辑代码抽象的不够,很多相同的逻辑重复实现,冗余代码较多,增加了维护的难度。

4.        随着业务需求的不断变化,已有的接口设计不能满足需要,需要进行接口层面的扩展。

如之前单一的根据后端回包中的 code 决定给前端回包的 result ,随着需求实现协议的增多,会出现不同协议返回相同 code 代表不同语义,需要输出不同的 result

5.        为了解决前端指令与后端接口存在先天的矛盾,需要 UI 从结构上灵活的支持组合指令。

产品为了提高用户体验,前端设计的趋势是要求大而全的接口,尽量减少与后端通信交互的次数。

UI 与后端服务的接口更注重的是接口语义的原子性,因此对 UI 的结构提出了更高的要求,需要能轻易地支持前端指令与多条后端接口的映射。

2.2          如何重构

在重构前花了一段时间整理所有指令的处理流程,事实证明这一步是非常有必要的。整理后把

系统的指令分为几类: welcome( 登陆 ) transfer( 通用上行指令 ) logout( 登出 ) pick( 异步获取消息 ) read( 其它 ) ,其中划为 transfer 的指令占据了绝大部分。除去相对特殊的 welcome 指令, transfer/logout/read 的指令处理流程相对类似,大致可以分为两步:解析上行请求组装发送后端请求包 (pack) 解析后端应答包格式化输出 json(format) 。区别在于组装的后端请求包格式不同,并且 transfer 的解析 / 格式化过程相对复杂,可能涉及到 username <–> uid 的转换。对于 pick ,可以把该指令进行划分成上下行:上行 pick 用于注册通知通道及保持用户在线,下行 notify 用于处理通知消息。经过这样划分, pick 的处理流程与 transfer 等指令几乎一致。

       对于 transfer 类指令,单独整理了其实现流程,流程图如下:

      

       从流程图可以看出, transfer 类型各条指令的区别在于:解析请求上行组装协议 xml(pack) 把后端响应包转化为 json(format) 。通过提取出通用的 pack format 接口,分别建立 pack format 的映射表,建立指令名称 (command) -> 指令对应接口实现 (function) 的映射关系,即可屏蔽掉这层差异,保证处理流程的统一。在 format 过程中,发现 json 回包中 result errorMessage 字段由后端响应包中的 code 和指令名称 (command) 决定。对这部分实现配置化,避免了代码中出现过多的 if/else 条件分支、新增指令时对程序的修改,便于模块的后续维护和升级。

       transfer 指令处理流程统一的前提下,组合指令的实现就变得水到渠成了。让每条组合指令从配置中读取需要执行的单条指令序列列表,遍历列表顺序执行每条指令,汇总执行结果输出即可。

组合指令的处理流程如下:

      

目前实现的组合指令相对比较简单,只是把多条指令的执行流程串行化,参数都在初始时全部传入,各条指令分别从初始的请求中解析参数,把各条指令的 json 包追加到结果中。即组合指令流程序列中各条指令没有明显的逻辑依赖关系,可以任意排列先后顺序。对于部分关键字段如 uid 做了特殊处理,会自动解析前一条指令应答包中的 uid ,作为下一条指令的请求参数。由于所有指令从公共数据存储 (mc_pack_t) 解析请求,并没有按请求区分参数,如果不同的请求参数重名时,会出现该参数无法区分的情形。

3          发散

考虑到当前的业务需求,组合指令目前的实现方式比较简单,还有较大的改进空间。初步整理了下,大致的改进点如下: 1 、为每条指令建立单独的请求参数存储; 2 、支持变化的指令序列,可以根据初始的请求参数决定指令序列; 3 、支持组合分页类的指令,即允许单条指令在组合列表中执行多次。

仔细深究组合指令的执行流程,发现与设计模式中的管道 - 过滤器模式比较类似。基于管道 - 过滤器模式的系统由管道和过滤器组成,每个处理步骤被封装成一个过滤器组件,数据在相邻过滤器之间通过管道传输。每个过滤器可以单独修改,功能相对单一,顺序可配置。


 

       针对管道和过滤器实现时一些关键的点,结合组合指令的实现方式进行分析如下:

l         分解系统任务成一系列的处理阶段

管道和过滤器实现的前提,在于把系统任务分割为相对独立的任务,任务之间没有明显的逻辑

依赖关系,仅关注前一个任务的输出数据流。这样通过数据流把各个任务串联起来,可以灵活替换某个步骤,实现不同的结果输出。 WEBIM-UI 中对组合指令按照后端独立接口分解成不同的指令,每条指令的逻辑处理可以看作一个过滤器,过滤器之间管道传输的数据流由三部分组成:去除前一指令解析参数后的请求、前一指令输出的部分参数 ( 可选 ) 和前一指令输出的中间结果。

l         定义沿管道传输的数据格式

对于每个过滤器,考虑到后续的扩展和灵活性,倾向于制定一个统一的数据格式。 WEBIM-UI

中指令之间传输的请求数据通过 mc_pack_t 表示,中间结果采用 json 表述。

l         如何实现过滤器链

所有的过滤器都服从统一的过滤器调用接口,则形成了过滤器链 (Filter Chain) ,常见过滤器链

连接是采用推的方式实现的,即在前一个过滤器流程运行结束时主动调用 FilterChain.next() 转到下一个过滤器。 WEBIM-UI 里采用维护指令列表下标的方式来标记当前运行的指令,在指令处理结束时对下标操作,指向下一步需要执行的指令。

l         设计和实现过滤器

对过滤器抽象出公共的 interface ,仔细划分每个过滤器的功能,实现对应接口即可。 WEBIM-UI

中抽象出 pack format 接口,建立每条指令到这两个接口实现的映射。

l         建立流水处理线

过滤器的部署可以通过配置文件指定其调用顺序, WEBIM-UI 中在配置文件中指定组合指令对

应的指令列表和各条指令的顺序。

除了这些共同点, WEBIM-UI 组合指令的实现与管道 - 过滤器的原则有一些区别,主要的区别在于目前组合指令的实现会共享状态信息,各条指令运行过程中会共同使用同一个上下文。

4          总结

有了清晰的重构目标,结合当前的业务需求,在深入了解业务流程的基础上抽象出公共的流程,

模块的重构之路变得简单很多。

 

 

 

 

 

 

WebIM说明 WebIM是一款基于jQuery的一款web即时通讯插件,姑且这么称呼吧。插件最大程度实现了IM的常用功能,除即时通讯的常用功能外,还加入了:消息盒子、窗口抖动、添加删除好友、最近联系人、超时登录界面、网站小秘书、聊天记录、发送频率限制、发送产品、发送名片、发送表情、产品分享、黑名单、举报、收藏、公告、智能网址过滤、消息提醒、修改资料、名片二维码、禁止粘贴、收起联系人列表、推荐好友等30余项改进。全浏览器兼容。 插件调用简单方便,只需在现有的web系统中加入几行代码,理论上可嵌入任何web系统。 2012年项目,已不再维护。 配置 $(function() { $(document).FnWebIM({ autoLogin :true, //boolean型,默认是否自动登录,true:自动登录,false:手动登录,默认为true msgRefreshTime :1000, //number型,消息刷新时间,单位为ms friendRefreshTime :10000, //number型,好友刷新时间,单位为ms showSecretary :true, //boolean型,默认是否显示小秘书,true:显示,false:不显示,默认为true noticeContent :"唐僧师徒历经千辛万苦,终于见到了佛祖……", //string型,公告内容 为空时不显示公告 sendPicture :true, //boolean型,是否允许发送图片,true:允许,false:不允许,默认为true msgMaxSize :300, //number型,单条消息最大允许字符 msgSound :false, //boolean型,是否开启声音提醒,true:开启,false:关闭,默认为true defaultWindow :"" //string型,登录后打开新聊天窗口,此处接收的参数为联系人的uid,否则会出错 }); }); 详细说明文档 http://www.zi-han.net/case/im/help.html 示例 http://www.zi-han.net/developer/721.html 注意 请在服务器(如localhost)环境下打开
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值