2.4.1 • Published 1 month ago

@xverse/xmit-core v2.4.1

Weekly downloads
-
License
ISC
Repository
-
Last release
1 month ago

TOC

Xmit Wasm SDK

Xmit 在 Web 端和小程序端使用的 SDK,通过 wasm 方式进行调用。

开发思路

先 xmit 主项目编译成动态库(interface.h, libxmit-solo.a),然后再通过 bridge 把 js 层跟 c++ 层的通信打通。

Web 端把 wasm 运行在 worker 环境中,所以需要主线程接口层 + worker 逻辑层 + wasm。为了避免出现请求失败的情况,编译的时候把 worker 跟 wasm 都内联在一起。

小程序端把 wasm 运行在主线程,所以只要主线程逻辑层 + wasm。由于小程序的 wasm 加载需要指定特定路径,所以不能把 wasm 内联进 js 代码中,需要生成独立的两个文件。

框架设计

Web 端

  • worker 线程
  1. 模块入口(src/worker/worker.ts),wasm 的初始化跟与主线程的通信主要放在这里。
  2. Client 模块(src/worker/xmit-client.ts),对应 xmit 协议的 client 概念,一个连接对应一个 client,一个 client 上有多个 stream 来收发消息。
  3. Engine 模块(src/worker/xmit-engine.ts),负责管理 Client。
  • 主线程
  1. 模块入口(src/xmit/index.ts),主要负责 wasm 跟 worker 的初始化,事件绑定,以及暴露一个创建 xmit 实例的接口;
  2. 具体xmit实例(src/xmit/instance.ts),跟 Client 概念对齐,创建 Stream、收发消息、连接状态回调。

小程序端

  1. 模块入口(src/mp/xmit.ts),负责 wasm 的加载,跟 wasm 的通信封装,以及暴露一个创建 xmit 实例的接口;
  2. Client 模块(src/mp/client.ts),对应 xmit 协议的 client 概念。
  3. Loader 模块(src/mp/glue.ts),小程序版本的 wasm 加载规则需要指定 wasm 文件的路径来加载,需要一个加载模块来实现指定路径加载的能力。
  • 小程序注意事项
  1. 小程序环境中没有 TextCodec API,需要自己加 polyfill。
  2. 小程序环境中没有 performance API,而 wasm 中的时钟获取依赖 js performance API,我们可以使用 wx.getPerformance 接口来平替。详情见 src/mp/performace.polyfill.js
  3. 小程序开发者工具跟真机的表现差异很大,调试的时候需要两边都兼容。

使用示例

Web

import Xmit, { StreamMode, StreamPriority } from '@xverse/xmit-core';

await Xmit.ready; // wasm 加载

// 如有 worker 之间通信的场景,则需要借助 MessageChannel
const channel1 = new MessageChannel();
channel1.port2.onmessage = (data: any) => {
  // ...
};
const xmit = Xmit.createInstance({
  messagePortConfigs: [{
    port: channel1.port1,
    // 独立纯函数,没有外部依赖和 this
    // 从主线程传参到 worker 线程过程中,参数是不能为函数的,所以会先把函数做一次 string 化处理,因此函数不能有外部依赖和 this。
    rule: (type, data) => {
      return true;
    },
  }, {
    // null 说明回给主线程
    port: null,
    // 独立纯函数
    hook: (type, data) => {
      return data.slice(2);
    },
  }],
});

// 各类事件回调注册
xmit.on('xxx', () => {});
...

// xmit 协议开始执行
xmit.start({
  cnid, // connection id,建连前跟后台交互协商获得
  externalTick, // 
});
// 创建发消息用的 stream,不同 stream 之间的区别是优先级和是否允许乱序,还有消息有效期。
const stream = xmit.createStream({
  label: 'xrtc-xmit-data',
  mode: StreamMode.SemiReliableOrdered,
  priority: StreamPriority.Normal,
  lifetimeMS: 3000,
});
stream.send(xxx);

...
// 断连后停止 xmit
xmit.stop();

小程序

因为小程序版本是运行在主线程的,不需要额外支持 worker 之间通信的能力。

import Xmit from 'path/to/xmit-core.js';

const XmitCore = new Xmit('path/to/wasm'); // 不需要包括文件名
await XmitCore.ready;

const xmit = XmitCore.createInstance();
// 各类事件回调注册
xmit.on('xxx', () => {});
...

// xmit 协议开始执行
xmit.start({
  cnid, // connection id,建连前跟后台交互协商获得
  externalTick,
});
// 创建发消息用的 stream,不同 stream 之间的区别是优先级和是否允许乱序,还有消息有效期。
const stream = xmit.createStream({
  label: 'xrtc-xmit-data',
  mode: StreamMode.SemiReliableOrdered,
  priority: StreamPriority.Normal,
  lifetimeMS: 3000,
});
stream.send(xxx);

// 断连后
xmit.stop();

构建与发布

因为 Coding 的 CI 环境过于老旧恶心难搞,目前还是通过本地构建的方式进行发布。

packages/xmit 目录下,执行 pnpm run build 进行构建,会同时输出 Web 版和小程序版产物。

Web 版发布

Web 版本的包变动通过执行 pnpm run release:fix/minor/major 来进行。

版本变更后,执行 npm publish --access public 进行发布。需要有 npm 发包权限。

小程序版发布

小程序的包需要手动修改 package-mp.json 文件。

发布时需要在 packages/xmit/mp-dist 目录下执行 npm publish --access public 进行发布。

使用方在安装后需要手动拷贝文件到开发目录中,例如 cpy node_modules/@xverse/xmit-mp-core/libxmit-mp.wasm ./js/libs/ --flat && cpy node_modules/@xverse/xmit-mp-core/xmit-core.js ./js/libs/ --flat。 (使用了 cpy-cli 这个 npm 包)。

2.4.1

1 month ago

2.4.0-alpha.0

3 months ago

2.3.4-alpha.4

3 months ago

2.3.4-alpha.5

3 months ago

2.3.4-alpha.6

3 months ago

2.3.4-alpha.3

3 months ago

2.3.4-alpha.0

4 months ago

2.3.4-alpha.1

4 months ago

2.3.4-alpha.2

4 months ago

2.3.3

4 months ago

2.3.2

5 months ago

2.3.2-alpha.0

5 months ago

1.2.0

9 months ago

1.2.5-sctp.5

7 months ago

2.2.1-alpha.0

6 months ago

1.2.5-sctp.2

7 months ago

1.1.0-alpha.11

9 months ago

1.2.5-sctp.1

7 months ago

1.1.0-alpha.10

9 months ago

1.2.5-sctp.4

7 months ago

1.2.5-sctp.3

7 months ago

2.2.3-alpha.1

6 months ago

2.2.3-alpha.0

6 months ago

1.2.5

7 months ago

1.2.4

8 months ago

1.2.3

8 months ago

1.2.2

8 months ago

1.2.1

9 months ago

1.0.3

10 months ago

2.2.1

6 months ago

2.2.0

6 months ago

2.2.2

6 months ago

2.2.3-alpha.3

6 months ago

2.2.3-alpha.2

6 months ago

2.0.0-alpha.0

7 months ago

1.2.4-node.2

8 months ago

2.0.0-alpha.1

7 months ago

2.0.0-alpha.2

7 months ago

1.2.4-node.1

8 months ago

1.2.4-node.0

8 months ago

2.0.0

7 months ago

2.2.0-wt.3

6 months ago

2.2.0-wt.2

7 months ago

2.2.0-wt.1

7 months ago

2.2.0-wt.0

7 months ago

1.1.1-alpha.0

9 months ago

1.1.1

9 months ago

1.1.0

9 months ago

1.1.2

9 months ago

2.3.0

5 months ago

2.3.1

5 months ago

1.1.0-alpha.9

9 months ago

1.1.0-alpha.7

9 months ago

1.1.0-alpha.8

9 months ago

1.1.0-alpha.1

10 months ago

1.1.1-decoder.0

9 months ago

1.1.0-alpha.2

10 months ago

1.1.0-alpha.0

10 months ago

1.1.0-alpha.5

9 months ago

1.1.0-alpha.6

9 months ago

1.1.0-alpha.3

10 months ago

1.1.0-alpha.4

9 months ago

1.2.5-sctp.0

7 months ago

2.1.0-alpha.1

7 months ago

1.0.2

11 months ago

1.0.2-beta.0

11 months ago

1.0.1

1 year ago

1.0.0

1 year ago

0.1.0-alpha.10

1 year ago

0.1.0-alpha.12

1 year ago

0.1.0-alpha.11

1 year ago

0.1.0-alpha.14

1 year ago

0.1.0-alpha.13

1 year ago

0.1.0-alpha.9

1 year ago

0.1.0-alpha.15

1 year ago

0.1.0-alpha.8

1 year ago

0.1.0-alpha.5

1 year ago

0.1.0-alpha.7

1 year ago

0.1.0-alpha.6

1 year ago

0.1.0-alpha.4

1 year ago

0.1.0-alpha.3

1 year ago

0.1.0-alpha.2

1 year ago

0.1.0-alpha.1

1 year ago

0.1.0-alpha.0

1 year ago