PC SDK 快速集成
此部分内容建议参考 Demo 项目源码 阅读
1. 获取凭据
集成 SDK 需要先在 小游戏宿主控制台 中创建应用,获得每个应用专属的 APP KEY, APP SECRET 及 Service Token 后。
启动 SDK 时,需要通过 APP KEY,APP SECRET 初始化。接入方也可联系 Unity 以创建 App Service Token / App Key / App Secret。
如下是测试用 App Service Token / App Key / App Secret 示例
- App Service Token
- App Key:
AKIDt1vMSYVFf1twI53iDecobx6QsTK0 - App Secret:
ufzN1iD8PsnMW0ViDCMhpJFBiLR1E1Xf
Service Token 的主要作用是调用以下 API 获取游戏 列表,并可从中获取 Game ID 以启动游戏。
实际生产环境中,Service Token 应该在服务端使用,从服务端调用上面的 API 。Demo 项目中,Service Token 是在客户端使用,这个仅仅是一个实例,不建议在生产环境中这样使用。
2. 导入 SDK
- SDK 支持 Windows 10+ / macOS 10.15+
- 将
webglhost-sdk-1.0.0.tgz和webglhost-runtime-pc-1.0.0.tgz添加到项目中。
安装依赖:
npm install ./webglhost-sdk-1.0.0.tgz ./webglhost-runtime-pc-1.0.0.tgz
或在 package.json 中添加:
{
"dependencies": {
"@webglhost/sdk": "file:./webglhost-sdk-1.0.0.tgz",
"webglhost-runtime-pc": "file:./webglhost-runtime-pc-1.0.0.tgz",
"electron": "^36.0.0"
}
}
导入模块:
const { TJHostHandle, RuntimeGameHandle, TJConstants } = require('webglhost-runtime-pc');
3. 初始化 SDK
初始化 Host SDK 内 TJHostHandle 后续游戏控制相关 API 依赖此实例,可通过检查 TJHostHandle.initialize 返回值是 否为空判断是否初始化成功。
function initTJHostHandle() {
// AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS is a test [Demo App Key]
// sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A is a test [Demo App Secret]
TJHostHandle.initialize('AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS', 'sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A', (hostHandle, error) => {
if (!hostHandle) {
return;
}
// 初始化完成 hostHandle
});
}
4. 启动单实例游戏
4.1 创建宿主
使用 TJHostHandle 初始化后的实例创建并初始化 RuntimeGameHandle,RuntimeGameHandle 作用于整个小游戏生命周期。
async function initGameHandle() {
const gameHandle = await hostHandle.createGameHandle();
// 初始化完成 RuntimeGameHandle
return gameHandle;
}
4.2 设置游戏启动参数
此处 Host SDK 将根据请求 Host Server 并根据 LAUNCH KEY 获取游戏包下载 URL 及游戏类型,全部参数列表参考 API Reference,成功后可加载游戏资源。
async function setGameStartOptions() {
const options = {};
options[TJConstants.LAUNCH_KEY] = 'LAUNCH KEY';
options[TJConstants.USER_ID] = 'guest';
await gameHandle.setGameStartOptions(options);
// 启动参数设置完成
}
4.3 加载游戏资源
成功后游戏窗口会被创建,游戏资源被下载并启动。
await gameHandle.start();
// 游戏加载完成
4.4 启动游戏
function showGame() {
if (!gameHandle) {
return;
}
gameHandle.play(); // 启动游戏
}
4.5 关闭游戏
添加关闭游戏监听回调,处理关闭游戏逻辑
gameHandle.setOnTJCloseListener(() => {
// 停止游戏
gameHandle.stop();
});
5. 多实例管理游戏
宿主提供了 MultiGameLauncher 管理多个游戏实例,当实例达到上限后会依据时间自动停止实例后作为新实例启用。
5.1 初始化多实例上限
const { MultiGameLauncher } = require('webglhost-runtime-pc');
MultiGameLauncher.configMaxGame(3); // 默认未初始化数量: 1
5.2 创建宿主
多实例创建宿主需要通过 gameId 来进行绑定,当实例已经创建过宿主则会复用原宿主。
// createGameHandle 时通过 gameId 找到绑定的实例
const gameHandle = await MultiGameLauncher.createGameHandle(hostHandle, gameId, {});
// 初始化完成 RuntimeGameHandle
5.3 设置游戏 启动参数
此处 Host SDK 将根据请求 Host Server 并根据 LAUNCH KEY 获取游戏包下载 URL 及游戏类型,全部参数列表参考 API Reference,成功后可加载游戏资源。
async function setGameStartOptions() {
const options = {};
options[TJConstants.LAUNCH_KEY] = 'LAUNCH KEY';
options[TJConstants.USER_ID] = 'guest';
await gameHandle.setGameStartOptions(options);
// 启动参数设置完成
}
5.4 加载游戏资源
成功后游戏窗口会被创建,并下载游戏资源。
await gameHandle.start();
// 游戏加载完成
5.5 启动游戏
function showGame() {
if (!gameHandle) {
return;
}
gameHandle.play(); // 启动游戏
}
5.6 暂停游戏
添加关闭游戏监听回调,处理暂停游戏逻辑
MultiGameLauncher.pause(gameId);
MultiGameLauncher.pauseAll();
5.7 恢复游戏
当游戏需要被恢复时,调用 resume 方法
const { MiniGameLaunchOption } = require('webglhost-runtime-pc');
// 设置热启动进入参数
const enterOption = new MiniGameLaunchOption({
scene: 1002,
shareTicket: '1002'
});
MultiGameLauncher.resume(gameId, enterOption);
// 不带参数恢复
MultiGameLauncher.resume(gameId);
5.8 停止游戏
当游戏需要被停止或需要释放页面时需调用 MultiGameLauncher.stop(gameId) 以释放所有关联信息
MultiGameLauncher.stop(gameId);
MultiGameLauncher.stopAll();
5.9 销毁实例
当实例需要被释放时需调用 MultiGameLauncher.destroy(gameId) 释放实例相关的内容,销毁实例会停止游戏并释放该实例
MultiGameLauncher.destroy(gameId);
MultiGameLauncher.destroyAll();
6. 事件监听
6.1 基础事件
// Game menu button clicked
gameHandle.setOnTJMenuListener(() => {
console.log('Menu clicked');
});
// Game close button clicked
gameHandle.setOnTJCloseListener(() => {
console.log('Close clicked');
gameHandle.stop();
});
// First frame rendered
gameHandle.setOnFirstFrameRenderedListener(() => {
console.log('First frame rendered');
});
// Game crashed
gameHandle.setOnHostFailureListener((error) => {
console.error('Game crashed:', error);
});
6.2 自定义命令
// Set custom command listener
gameHandle.setCustomCommandListener('customCommand', (request, handle) => {
console.log('Custom command received:', request);
handle.success({ result: 'success' });
});
// Run custom script in game
await gameHandle.runCustomScript(`
console.log('Hello from game!');
tj.customCommand({
command: 'customCommand',
data: { message: 'Hello from game!' }
});
`);
7. 音频控制
// Mute all audio
gameHandle.muteAllAudio();
// Unmute all audio
gameHandle.unmuteAllAudio();
// Toggle audio mute
gameHandle.toggleAudioMute();
// Check if muted
const isMuted = gameHandle.isMuted();
8. 调试功能
// Open debug menu
gameHandle.showDebugMenu();
// Toggle debug mode
gameHandle.toggleDebugMode();
// Get debug mode status
const debugEnabled = gameHandle.getDebugModeStatus();
// Force garbage collection
gameHandle.invokeForceGC();
// Export logs
gameHandle.exportLogManagerLog();
9. API 参考
TJConstants
游戏启动参数常量:
const TJConstants = {
LAUNCH_KEY: 'launchKey', // Game launch key (required)
GAME_ID: 'gameId', // Game ID
USER_ID: 'userId', // User ID
ACCESS_TOKEN: 'accessToken', // Access token
ENABLE_VCONSOLE: 'enableVConsole', // Enable vConsole
ENABLE_INSPECTOR: 'enableInspector', // Enable inspector
ENABLE_MUTE_ALL_AUDIO: 'enableMuteAllAudio', // Mute all audio
ENABLE_TRANSPARENT_MODE: 'enableTransparentMode', // Transparent mode
INSPECTOR_WAIT_FOR_INSPECT: 'waitForInspect', // Wait for inspect
};
TJHostHandle
Static Methods
initialize(sdkKey, sdkSecret, completion)- Initialize SDKsetRuntimeEnv(env)- Set runtime environmentgetVersionName()- Get version namegetVersionCode()- Get version codegetCommitId()- Get commit ID
Instance Methods
createGameHandle(options)- Create game handleinitLog(logLevel, logger)- Initialize loggingsetRecentlyGameListener(listener)- Set recently played game listenergetUserHistory(userId)- Get user history
RuntimeGameHandle
Lifecycle Methods
setGameStartOptions(options)- Set game start optionsstart()- Start game (download and initialize)play()- Play gamepause()- Pause gamestop()- Stop gamerestart()- Restart game
Event Listeners
setOnTJMenuListener(callback)- Menu button clickedsetOnTJCloseListener(callback)- Close button clickedsetOnFirstFrameRenderedListener(callback)- First frame renderedsetOnHostFailureListener(callback)- Game crashedsetCustomCommandListener(command, callback)- Custom command
Audio Control
muteAllAudio()- Mute all audiounmuteAllAudio()- Unmute all audiotoggleAudioMute()- Toggle audio muteisMuted()- Check if muted
Debug Methods
showDebugMenu()- Show debug menutoggleDebugMode()- Toggle debug modegetDebugModeStatus()- Get debug mode statusinvokeForceGC()- Force garbage collectionexportLogManagerLog()- Export logs
MultiGameLauncher
Static Methods
configMaxGame(max)- Configure max instancescreateGameHandle(hostHandle, gameId, options, completion)- Create game handlestopAll()- Stop all instancesstop(gameId)- Stop specified instancepauseAll()- Pause all instancespause(gameId)- Pause specified instanceresume(gameId, enterOption)- Resume specified instancedestroyAll()- Destroy all instancesdestroy(gameId)- Destroy specified instance
Query Methods
getGameHandle(gameId)- Get game handlegetAllTasks()- Get all tasksgetActiveGameCount()- Get active game countisMaxReached()- Check if max reached
10. 错误处理
const { HostRuntimeError } = require('webglhost-runtime-pc');
try {
const hostHandle = await TJHostHandle.initialize('invalid-key', 'invalid-secret');
} catch (error) {
if (error instanceof HostRuntimeError) {
switch (error.code) {
case 'SDK_INITIALIZATION_FAILED':
console.log('SDK initialization failed');
break;
case 'GAME_ID_NOT_SET':
console.log('Game ID not set');
break;
case 'LAUNCH_KEY_NOT_SET':
console.log('Launch key not set');
break;
default:
console.log('Unknown error:', error.message);
}
}
}
11. 系统要求
- Node.js: >= 20.0.0
- Electron: >= 32.0.0
- Operating Systems:
- Windows 10+ (x64)
- macOS 10.15+ (x64, arm64)
12. 注意事项
- Electron 环境: SDK 必须在 Electron 环境中运行
- 单例模式: TJHostHandle 建议使用单例模式,避免重复初始化
- 资源清理: 游戏关闭时务必调用
stop()或destroy()方法释放资源 - 多实例管理: 使用 MultiGameLauncher 时注意配置合理的最大实例数,避免资源占用过高
- 错误处理: 所有异步操作都应添加适当的错误处理
- 日志记录: 生产环境建议启用日志记录功能,便于问题排查
13. 高级使用场景
想要深入了解更多高级功能,请参考: