云信IM SDK接口设计实践

IM (Instant Messaging) 是网络上最流行的通信方式,与日常生活息息相关。 IM 软件也层出不穷,例如:微信、 QQ 、易信等。通过多年深耕和技术沉淀,云信产出了一套成熟稳定的 IM SDK 架构。它提供了 IM 的主要功能,大大降低了第三方实现 IM 功能的难度。本文主要对 IM 接口设计实践展开论述。

作者:陈吉力 网易智慧企业高级 Android 开发工程师

一、对外接口的设计准则

SDK 对外提供接口设计的基本原则是易用,易懂,易扩展,易监控。展开来可归纳为以下几个特性:

1. API 按照业务功能分类,但所有业务具有统一的调用风格。

2. API 不包含方法实现,接口的实现对调用者隐藏。

3. API 调用可跟踪。

在功能形式上, SDK 需要提供以下类型的 API :

1. 功能接口:主动调用使用其提供的功能

1.1. 同步接口:在调用线程完成函数调用,并立即返回结果。

1.2. 普通异步接口:在后台线程完成函数调用,可以添加回调函数。

1.3. 可中断异步接口:在后台线程完成函数调用,可以添加回调函数,可以中断调用。

2. 回调接口:监听数据和状态改变。

二、业务的分类

SDK 包含多种业务,一部分是基础业务,另一部分是可选业务。比如用户认证服务、群服务等是基础业务;超大群服务、第三方推送服务等是可选业务。

另外,不同的业务之间难免有相似的功能,如群服务和超大群服务中,都有添加群成员,拉取群消息等功能。因此,需要将不同的业务进行隔离,一方面方便业务功能的扩展与调整,另一方面方便函数的命名与用户的理解。

同一个业务下有多个 API ,按照调用的主动性,分为回调接口和功能接口,分别放在与业务一一对应的接口类 Observer 和 Service 中。

例如:用户认证服务下的所有回调接口和功能接口都位于 AuthServiceObserver 和 AuthService 中。其中由用户主动调用来实现功能的功能接口在 AuthService 中,如登录、登出等;而用于注册回调的回调接口都在 AuthServiceObserver 中,如监听在线状态、监听数据同步等。

每个 Service 中的功能接口根据执行的性质又分为三种,同步接口、普通异步接口和可中断异步接口。

其中同步接口在调用线程立即执行;异步接口在后台线程执行,在调用线程返回可设置回调的 InvocationFuture 类型,最终结果在主线程回调;可中断异步接口和普通异步接口相似,但是返回的是继承自 InvocationFuture 的 AbortableFuture 类型,支持中断操作,用户可以通过主动调用来中断功能接口的执行。

接口调用的线程切换流程如图 2.1 所示,业务功能和接口的分类如图 2.2 所示。

云信IM SDK接口设计实践

Figure 1接口调用的线程切换流程

云信IM SDK接口设计实践

Figure 2业务功能和接口的分类

三、API的实现

(一) API的实现方式 

为了实现这些目标,并考虑到实现简单,我们选用 Java 的动态代理类模型。

外部调用者调用 API 时,得到一个动态代理(Proxy) 对象,通过 Proxy 对象,将功能接口的调用全部转接到一个实现了 InvocationHandler 接口的类 ProxyHandler 上。

再根据调用方法,执行注册/注销回调或者将调用请求分派到真正的实现类上,最后根据接口的返回类型进行返回或回调,如图 3.1 所示。

云信IM SDK接口设计实践

Figure 3功能调用流程

和用户服务的接口类 AuthService 和 AuthServiceObserver 一样, SDK 也为其他的所有业务定义了接口类。

所有接口类和实现类呈一一对应关系,可以方便地找到 API 对应的实现。

 (二)获取Proxy对象的方法 

SDK对外提供了静态方法 NimClient.getService(Class<T> clazz) 来获取业务接口类对应的动态代理类。参数填入对应的接口类即可。

例如:获取用户认证服务的接口类的方式为:

NimClient.getService(AuthService.class),获取用户认证服务观察者的接口类的方式为 NimClient.getService(AuthServiceObserver.class)。

NimClient.getService 方法同步返回一个 Proxy 对象。该对象的构造方式为懒加载,业务被调用的时候才构造对应实例。如图 3.2 所示。

云信IM SDK接口设计实践

Figure 4获取业务Proxy对象流程

生成 Proxy 对象基于 Proxy.newProxyInstance 方法,所有生成的 Proxy 对象都由专门的容器类来管理。

以用户认证服务为例,名列前茅次调用 NimClient.getService(AuthService.class) 获取用户认证服务的 Proxy 对象时,容器理类创建一个对应的 Proxy 对象并缓存。

之后再次获取用户认证服务 Proxy 对象时,容器类将缓存直接返回。

(三) 事物跟踪类 

Invoke 函数中有一个重要的事务跟踪类 (Transaction),它记录了方法的同步异步属性、方法体和返回值要求等。Transaction 对象和他的实现方法是一一对应的。每次执行 invoke 方法,都会创建一个 Transaction 实例,并传输到真正的执行点去执行。

执行完毕后, invoke 方法根据同步异步特性以及返回值,来确定功能函数的返回结果。如果是同步函数,则直接返回结果;如果是异步函数,则根据业务需求返回 InvocationFuture 或者 AbortableFuture。

 (四)API的执行方式 

NimClient.getService 返回的是动态代理类 ProxyHandler,它实现了 InvocationHandler 接口的 Object invoke(Object who, Method method, Object[] args) 方法,用于代理所有功能接口。

API 执行方式,即 ProxyHandler 对 invoke 方法的实现方式,其大体步骤是加载事务、初始化判断、执行事务和返回,如图 3.3 所示。

云信IM SDK接口设计实践

Figure 5代理执行的简要流程

执行事务这一环节还可以细分为回调接口的执行和功能接口的执行,如果是执行回调接口,则判断是否需要回调当前状态,如果是,则立即回调。

Transaction 的执行函数是 TransactionExecutor. execute 方法,送出 Transaction 后, invoke 方法会根据同步异步属性,决定是在当前线程执行,还是在后台线程执行。用于异步执行 Transaction 的后台线程是少数的,如果有多个 Transaction 需要被异步执行,则会阻塞。

接口类的每个方法都被存进一个 Map 中, SDK 以方法签名实现了同名函数重载。执行 Transaction 时,通过方法所在的接口类找到对应的实现类,再调用对应的 invoke 方法即可。对于异步方法, invoke 方法的返回值不会被返回到上层,因此异步 API 函数的实现不用关心返回值。代理的详细执行流程如图 3.4 所示。

云信IM SDK接口设计实践

Figure 6代理的详细流程

(五) 异步方法的回调

对于异步方法,在 TransactionExecutor. execute 执行前,先基于 Transaction 生成对应的 AbortableFuture 的实现类 TransactionFuture ,然后将其缓存,用于稍后的回调。异步方法执行完毕后,将子类返回到调用层。

在调用可中断异步接口后,同步返回的是 AbortableFuture 实例。调用方可以直接调用abort 方法中止执行。

例如:调用了用于下载消息附件的 downloadAttachment 函数后,由于文件太大,网络状况不好等情况需要取消下载时,可以主动调用 abort 方法来终止。调用方式如图 3.5 所示。可中断异步接口对应的 abort 方法由 SDK 内部实现,调用者不需要关心其实现方式。

云信IM SDK接口设计实践

Figure 7abort函数调用示例

TransactionFuture 回调的基本类型为 RequestCallback,SDK 在此基本类型中定义了 onSuccess、onFailed 和 onException 函数,分别用于在成功、失败和异常情况下根据执行结果的不同,回调到不同的函数。到此整个流程结束。

四、总结

云信 IM 中,用户可以通过 NimClient.getService 方法选择业务的动态代理,然后根据业务需求在调用线程或者后台线程执行功能,最后直接返回或者回调结果。

如果调用的是可中断异步接口,用户还可以中断操作。基于动态代理的实现方式,隔离了其他业务下的对外接口,并解耦了接口和实现,配合代码混淆,更进一步的提升隔离效果。

作者介绍

陈吉力,网易智慧企业高级 Android 开发工程师。本硕就读于电子科技大学,毕业后从事云信 IM SDK Android 端的开发工作,喜爱篮球,羽毛球等。

关于网易云信

网易云信:网易智企旗下融合通信云服务专家、通信与视频 PaaS 平台。集网易 24 年 IM 以及音视频技术打造的融合通信云服务专家,稳定易用的通信与视频 PaaS 平台。提供融合通信与视频的核心能力与组件,包含 IM 即时通讯、5G 消息平台、一键登录、信令、短信与号码隐私保护等通信服务,音视频通话、直播、点播、互动直播与互动白板等音视频服务,视频会议等组件服务,并联合网易易盾推出一站式安全通信方案「安全通」。目前,网易云信已经成功发送 1.6 万亿条消息,覆盖智能终端 SDK 数累计超过 186 亿,我们期待每个智能终端都有云信的融合通信能力。

文章标题:云信IM SDK接口设计实践,发布者:网易智企,转载请注明出处:https://worktile.com/kb/p/6000

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
网易智企的头像网易智企
上一篇 2022年3月17日 上午12:42
下一篇 2022年3月17日 上午12:47

相关推荐

  • 学编程PLC要买什么电脑

    学习PLC编程不必购置高性能电脑,主要关注三个方面: 1、处理器性能、2、稳定的内存容量、以及3、足够的硬盘存储。在处理器性能方面,多数PLC编程软件对CPU的要求不高,但考虑未来学习的可能性扩展和软件的更新,选择具有较好性能的处理器能保证软件运行的流畅度和未来的兼容性,例如,中高端的i5或i7处理…

    2024年5月16日
    11900
  • 用什么编程公式炒股好

    实现股市自动化交易的成功率较高的几种编程公式分别是移动平均线交叉、相对强弱指数(RSI)、MACD交叉和量价分析。在这些方法中,移动平均线交叉是一种常用的技术分析工具,它基于两条不同周期的移动平均线之间的关系来决定买卖时机。当短期平均线从下方穿越长期平均线时,通常被解释为买入信号,反之则为卖出信号。…

    2024年5月16日
    5800
  • 新手编程序用什么软件

    新手编程推荐使用的软件有1、Visual Studio Code、 2、Sublime Text、 3、Atom。 对于初学者来说,Visual Studio Code(VS Code)是一个十分理想的选择。它是由微软开发的一款免费、开源的编辑器,支持多种编程语言,并且具有强大的社区支持。VS Co…

    2024年5月16日
    8300
  • 编码编程是什么意思

    编码编程是1、使用编程语言将指令转换成机器可以执行的代码、2、软件开发过程中的一个重要环节。在这个过程中,最显著的特点是将解决问题的策略和逻辑用具体的编程语言形式表达出来。这就需要开发者不仅要掌握一门或多门编程语言,还需要具备逻辑思维和解决问题的能力。通过编码,开发者能够让计算机执行特定任务,从而达…

    2024年5月16日
    2800
  • 网上教编程的是什么

    网上教授编程主要是通过数字平台向用户提供编程知识与技能的学习资源和指导。在这种方式中,互动式教学特别受到重视,因为它能够模拟真实的编程环境,让学习者在实践中掌握知识。这种教学方法不仅包括视频课程、在线讲座和实时代码编写实践,还可能涵盖编程挑战和项目构建等元素,用以增强学习者的实战能力。 I、互动平台…

    2024年5月16日
    3400

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部