适配器开发指引
@cloudbase/js-sdk 只支持常规 Web 应用(即浏览器环境)的开发,不兼容其他类 Web 平台,比如微信小程序、快应用、Cocos 等。虽然这些平台大多支持 JavaScript 运行环境,但在网络请求、本地存储、平台标识等特性上与浏览器环境有明显差异。针对这些差异特性,@cloudbase/js-sdk 提供一套完整的适配扩展方案,遵循此方案规范可开发对应平台的适配器,然后搭配 @cloudbase/js-sdk 和适配器实现平台的兼容性。
适配规范
开发适配器之前需要安装官方提供的接口声明模块@cloudbase/adapter-interface:
# npm
npm i @cloudbase/adapter-interface
# yarn
yarn add @cloudbase/adapter-interface
适配器模块需要导出一个adapter对象:
const adapter = {
genAdapter,
isMatch,
// runtime标记平台唯一性
runtime: '平台名称'
};
export adapter;
export default adapter;
必须包含以下三个字段:
runtime:string,平台的名称,用于标记平台唯一性;isMatch:Function,判断当前运行环境是否为平台,返回boolean值;genAdapter:Function,创建adapter实体。
runtime
runtime用于标记平台的唯一性,建议尽量以平台的英文名称或简写命名,比如百度小程序baidu_miniapp、QQ 小程序qq_miniapp等等。
isMatch
isMatch函数用于判断当前运行环境是否与适配器匹配,通常是通过判断平台特有 的一些全局变量、API 等。比如以下代码是判断运行环境是否为 Cocos 原生平台:
function isMatch(): boolean {
if (typeof cc === "undefined") {
return false;
}
if (typeof WebSocket === "undefined") {
return false;
}
if (typeof XMLHttpRequest === "undefined") {
return false;
}
if (!cc.game) {
return false;
}
if (typeof cc.game.on !== "function") {
return false;
}
if (!cc.game.EVENT_HIDE) {
return false;
}
if (!cc.game.EVENT_SHOW) {
return false;
}
if (!cc.sys) {
return false;
}
if (!cc.sys.isNative) {
return false;
}
return true;
}
genAdapter
genAdapter函数返回适配器的实体对象,结构如下:
interface SDKAdapterInterface {
// 全局根变量,浏览器环境为window
root: any;
// WebSocket类
wsClass: WebSocketContructor;
// request类
reqClass: SDKRequestConstructor;
// 无localstorage时persistence=local降级为none
localStorage?: StorageInterface;
// 无sessionStorage时persistence=session降级为none
sessionStorage?: StorageInterface;
// storage模式首选,优先级高于persistence
primaryStorage?: StorageType;
// Captcha验证码配置
captchaOptions?: {
// 打开网页并通过URL回调获取 CaptchaToken,针对不同的平台,该函数可以自定义实现
openURIWithCallback?: (url: string) => Promise<CaptchaToken>;
};
// 获取平台唯一应用标识的api
getAppSign?(): string;
}
示例
import {
AbstractSDKRequest,
IRequestOptions,
IUploadRequestOptions,
StorageInterface,
WebSocketInterface,
WebSocketContructor,
SDKAdapterInterface,
StorageType,
formatUrl,
} from "@cloudbase/adapter-interface";
// isMatch函数判断当前平台是否匹配
function isMatch(): boolean {
// ...
return true;
}
// Request类为平台特有的网络请求,必须实现post/upload/download三个public接口
export class Request extends AbstractSDKRequest {
// 实现post接口
public post(options: IRequestOptions) {
return new Promise((resolve) => {
// ...
resolve();
});
}
// 实现upload接口
public upload(options: IUploadRequestOptions) {
return new Promise((resolve) => {
// ...
resolve();
});
}
// 实现download接口
public download(options: IRequestOptions) {
return new Promise((resolve) => {
// ...
resolve();
});
}
}
// Storage为平台特有的本地存储,必须实现setItem/getItem/removeItem/clear四个接口
export const Storage: StorageInterface = {
setItem(key: string, value: any) {
// ...
},
getItem(key: string): any {
// ...
},
removeItem(key: string) {
// ...
},
clear() {
// ...
},
};
// WebSocket为平台特有的WebSocket,与HTML5标准规范一致
export class WebSocket {
constructor(url: string, options: object = {}) {
const socketTask: WebSocketInterface = {
set onopen(cb) {
// ...
},
set onmessage(cb) {
// ...
},
set onclose(cb) {
// ...
},
set onerror(cb) {
// ...
},
send: (data) => {
// ...
},
close: (code?: number, reason?: string) => {
// ...
},
get readyState() {
// ...
return readyState;
},
CONNECTING: 0,
OPEN: 1,
CLOSING: 2,
CLOSED: 3,
};
return socketTask;
}
}
// genAdapter函数创建adapter实体
// options 为 cloudbase.useAdapters(adapter, options) 时传入的参数
function genAdapter(options) {
const adapter: SDKAdapterInterface = {
// root对象为全局根对象,没有则填空对象{}
root: window,
reqClass: Request,
wsClass: WebSocket as WebSocketContructor,
localStorage: Storage,
// 首先缓存存放策略,建议始终保持localstorage
primaryStorage: StorageType.local,
// sessionStorage为可选项,如果平台不支持可不填
sessionStorage: sessionStorage,
};
return adapter;
}
// 三者缺一不可
const adapter = {
genAdapter,
isMatch,
// runtime标记平台唯一性
runtime: "平台名称",
};
export default adapter;
接入流程
第 1 步:安装并引入适配器
安装 @cloudbase/js-sdk 和所需平台的适配器,比如 QQ 小游戏平台:
# 安装 @cloudbase/js-sdk
npm i @cloudbase/js-sdk
# 安装 QQ 小游戏适配器
npm i cloudbase-adapter-qq_game
然后在业务代码中将引入适配器:
import cloudbase from "@cloudbase/js-sdk";
import adapter from "cloudbase-adapter-qq_game";
// options传入后,可以在 adapter 的 genAdapter 中获取到该参数
cloudbase.useAdapters(adapter, options);
第 2 步:初始化云开发
在业务代码中初始化云开发
import cloudbase from '@cloudbase/js-sdk';
import adapter from 'cloudbase-adapter-qq_game';
cloudbase.useAdapters(adapter);
cloudbase.init({
env: '环境ID',
})