# 前言
本章主要和大家一起实现一个具有中间件,事件等功能的可扩展的SDK,基于此基础SDK, 从而实现云信聊天SDK模块。

上图是这样和大家讲解的核心模块,具体源码可以参考如下仓库地址,对应的NPM安装包如下:tbms-middleware、 tbms-sdk、tbms-brandsdk-yunxin 和 generator-typescript-jest-sdk。
- 中间件源码(tbms-middleware): github.com/ge-tbms/tbm…
- 基础SDK源码:github.com/ge-tbms/tbm…
- 云信SDK源码:github.com/ge-tbms/tbm…
- SDK生成脚手架源码:github.com/ge-tbms/gen…
# tbms-midddleware 设计思想
tbms-middleware 的设计参考了Koajs的设计原理。Koajs的中间件思路: 中间件对于一次请求来处理,context分别集成了request和response对象。
同理可以映射成对一条收发消息的处理,通过dispatch,经过中间件流转,转化成系统期望的数据结构。
在context中会集成 message(消息) , session(会话) , app(如用户,初始化sdk信息等其他信息)

解释说明:websocket 接受一条数据流,通过 action 触发 dispatch 方法, dispatch 会触发各个 middleware 模块,同时一直保存着 context执行上下文。在视图层同样通过 action 触发 dispatch, 回流到 view 层。
# tbms-middleware 核心实现
tbms-middleware 模块继承于 tbms-util 的 EventEmitter 事件类(此实现源码在通用SDK设计中实现过),因此 tbms-middleware 模块具有事件发布-订阅模式。
# tbms-middleware-compose 核心代码
export default function compose(middleware: ICallback[]) {
/**
* 中间件返回函数
* @param {Array} middleware
* @return {Function}
*
*/
return function(context: object, next?: Promise<any> | ICallback) {
let index: number = -1;
// 0. 执行 dispatch 递归模块
return dispatch(0);
// 1. 实现 dispatch 函数,返回Promise链
function dispatch(i: number): Promise<any> {
if (i <= index)
return Promise.reject(new Error("next() called multiple times"));
index = i;
let fn: any = middleware[i];
// 2.1 如果递归索引值为模块长度,赋值next,
// 2.2 同时next为空的时候,返回 promise resolve,跳出递归。
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve(context);
try {
// 3. i+1 递归执行下一个Middleware模块
r