在Android IM即时通讯多进程中间件规划与完成 一文中首要的点有两个
- 多进程完结客户端和服务端的通讯
- 通讯的介质
让SDK更通用
整个完成中其实我是不Core你究竟运用websocket仍是自己撸的TCP仍是其他,我关心的是多进程中间件的完成。
所以咱们要做一个规划,我期望在我的整个Demo 中不关心长链接的具体完成,可是我能在Demo 对整个长衔接进行办理、运用,我的目标是:
- 在运用Demo时不需要考虑长衔接的完成方法
- 在任何现已存在的长衔接代码中,此Demo 均能完成其多进程中间件的责任
这样规划的优势在哪里?
- 能够更多的作为一个开放平台
- 不管以后发展中出现多牛逼的长衔接方法,都不影响咱们的事务
这个规划会具备以下特色
- 涉及核⼼功用统⼀办理升级;
- 确保核⼼功用具备⾼灵敏替换性;
- Demo与长衔接结构完全剥离,项⽬⾯向中间层编码,⽆须了解实际完成SDK
物理结构
中间件构成独⽴SDK,项⽬⾯向图⽚加载结构编码,一切功用统⼀办理;依靠联系⻅下图:
多进程中间件
当前的组件规划核⼼思想是彻底弱化长衔接在项⽬中的界说,达到项⽬直接与IMClient接触,终极⽬标是项⽬只知道IMClient⽽不知道长衔接,所以全体SDK呈现出了如下图的组件架构形式: 能够包含了多个不同的组件
具体完成
运用依靠回转原则进行高层逻辑完成
- LongConnectService
/**
* Create by kpa(billkp@yeah.net) on 2023/3/13
* 16:58
* Describe :整个完成中其实我是不Core你究竟运用websocket仍是自己撸的TCP仍是其他,
* 我关心的是多进程中间件的完成。所以咱们对这部分做一个
* 笼统衔接器
*/
interface LongConnectionService {
/**
* 初始化长衔接实例
*/
fun initLongConnection()
/**
* 衔接长衔接
*/
fun connect()
/**
* 断开长衔接
*/
fun disConnect()
/**
* 重新衔接长衔接
*/
fun reConnect()
}
然后咱们运用笼统工厂形式供给对长衔接器的一致创立
修改中间件IMClient
关于SDK⽽⾔,长衔接器操作、装备等,需要供给统⼀的装备类以供APP进⾏配,可运用Builder形式,封装其责任,总的来说他将变为APP对其装备和操作的东西
class IMClient private constructor(builder: Builder) {
private var longConnectionFactory: IMLongConnectionFactory<LongConnectionService>? = null
init {
longConnectionFactory = builder.getFactory()
}
//...
companion object {
@Volatile
private lateinit var mInstance: IMClient
fun isInstalled() = this::mInstance.isInitialized
@JvmStatic
fun init(imClient: IMClient): IMClient {
synchronized(IMClient::class) {
if (!isInstalled()) {
mInstance = imClient
} else {
throw RuntimeException("现已初始化")
}
}
return mInstance;
}
@JvmStatic
fun with(): IMClient {
if (isInstalled()) {
throw RuntimeException("未初始化")
}
return mInstance;
}
}
class Builder {
private var mFactory: IMLongConnectionFactory<LongConnectionService>? = null
fun withFactory(factory: IMLongConnectionFactory<LongConnectionService>) = apply {
this.mFactory = factory
}
//如果不设置长衔接器,将默认本Demo 中的DefaultWebsocketFactory
fun getFactory(): IMLongConnectionFactory<LongConnectionService> {
if (mFactory == null) {
mFactory = DefaultWebsocketFactory.create()
}
return mFactory!!
}
fun build(): IMClient {
return init(IMClient(this))
}
}
//...
}
中间件运用
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
// 初始化
IMClient.Builder()
.withFactory(DefaultWebsocketFactory.create()).build()
// 运用
IMClient.with().connect()
IMClient.with().send("我是发送的音讯内容")
怎样接入自己的长衔接代码
通过上面的类图,信任大家现已知道怎样接入了。
- 完成LongConnectionService 高级笼统
class DefaultLongConnectionImpl(private val mContext: Context) : LongConnectionService {
override fun initLongConnection() {
TODO("Not yet implemented")
}
override fun connect() {
TODO("Not yet implemented")
}
override fun disConnect() {
TODO("Not yet implemented")
}
override fun reConnect() {
TODO("Not yet implemented")
}
}
- 创立对应的工厂创立器
class DefaultWebsocketFactory : IMLongConnectionFactory<DefaultLongConnectionImpl>() {
companion object {
@JvmStatic
fun create(): DefaultWebsocketFactory {
return DefaultWebsocketFactory()
}
}
override fun createLongConnection(context: Context): DefaultLongConnectionImpl {
return DefaultLongConnectionImpl(context)
}
}
具体的流程规划
拒绝侵入三方SDK,让你的事务独立起来
在⽅案规划中,完结了项⽬与IMClient 的衔接,也规划了核⼼长衔接的的切换、功用笼统等⼯作,可是还存在以下问题:
- 长衔接的代码关于运用自己代码的同学,他是关于的无用的
- 组件的责任不明确
可是处理方法极端简单,咱们只需要将笼统的高层逻辑部分移动到其他组件中,在组件层面,也便是代码仓库中隔脱离,这将不再存在以上问题。
总结
这种规划方法在开发中使用场景很多,基本上一切运用第三方组件的场景都应该依照如此规划,这样既能确保事务不受损害,在将来事务走上正轨也不影响你替换组件,这样咱们就做到了:
- 控制回转
- 组件层级分明
- 各组件间物理阻隔
- 依据需求单独打包 (⽐如项⽬研制接⼊了2款长衔接结构,上线时只需要其中之一,即将需要的进⾏物 理依靠,其他的取消依靠即可)
- 去除IMClinet中⼼化,多⼈开发不受影响(开发中间件和长衔接将变成两个事务)
- 提升了组件稳定性
当然,组件的事务杂乱程度不是我关心的,可是大家能够进行提取,丰厚自己的事务。
代码:
github.com/kongxiaoan/…