API 深度交互
概述
此文档主要包含客户端深度交互的使用方式以及动作列表,接入源码参考 https://github.com/JorMi-03/DJBridge
动作列表
2J 发送动作给平台
action | data | 描述 | ||
---|---|---|---|---|
2J 会自动执行的动作 | ||||
htmlPageShow | / | Html 页面已经显示出来了,如何修复启动白屏可以在接受到这个动作后执行显示 | ||
loadFrameworkStart | / | 开始加载框架(这里已经加载完成了引擎及框架主代码) | ||
loadFrameworkEnd | / | 框架加载完成(初始框架及框架包含的公共资源) | ||
showGameRoomView | / | 显示游戏房间界面 | ||
showGameView | / | 显示游戏界面 | ||
firstAssetsLoadEnd | / | 首次资源加载完成(首次显示了房间列表 / 游戏界面) | ||
notSufficientAmount | { // 需要的余额 amout: number gameId: number rechargeFrom: number } | 余额不足 (如果使用了applyActions注册,将会忽略2J的默认行为) rechargeFrom: 8: 余额不足 10: 子游戏结算余额不足 11: 子游戏下注余额不足 12: 子游戏进入房间余额不足 | ||
需要执行applyActions后才能使用的动作 | ||||
closeGame | / | 关闭游戏(平台需要再这里关闭2J的游戏窗口"iframe/webview") |
平台发送动作给 2J
action | send data | callback data | 描述 | |
---|---|---|---|---|
以下动作接受到loadFrameworkStart推送后可执行 | ||||
applyActions | Array<string> | / | 申请可以生效的2J To Bridge 动作,需要申请的动作2J有默认行为,申请后2J将会忽略默认行为使用平台提供的动作 | |
setMusicOpen | boolean | / | 设置音乐开关(控制的是背景音乐) | |
setEffectOpen | boolean | / | 设置音效开关 | |
isMusicOpen | / | boolean | 音乐是否开启 | |
isEffectOpen | / | boolean | 音效是否开启 | |
以下动作必须接受到loadFrameworkEnd推送后才可执行 | ||||
openDebug | / | / | 开启API游戏debug功能 | |
以下动作接受到firstAssetsLoadEnd首次资源加载完成推送后可执行 | ||||
getScreenshotBase64 | / | string | 获取截图base64数据,平台可以根据这个数据模拟在2J游戏界面显示平台的弹框,(注: 首次游戏画面未显示的情况获取的数据是错误的) | |
gamePause | / | / | 暂停游戏主循环(在一些平台的界面性能需要优化的情况下,可以暂停游戏) | |
gameResume | / | / | 恢复游戏主循环 | |
getGameViewType | / | / | 获取游戏当前界面类型 0: 未知 1: 房间列表 2: 游戏界面 | |
getAllRoomInfo | / | { gameId: number items: { id: number; betList: number[] } } | 获取所有房间列表配置数据 (注:仅slots及百人场有betList) 下注档位(以slots举例),每款slots都会有下注bet的档位 | |
updateUserBalance | / | / | 手动刷新用户余额 | |
以下动作必须在显示游戏界面的情况下可使用 | ||||
getRoomInfo | / | { gameId: number betList: number[] } | 获取当前进入房间配置数据 |
接入示例
平台向 2J 发送动作
iframe 方式
js
const message = {
action: action,
data: data,
callbackId: callbackId,
};
this.iframe.contentWindow.postMessage(message, this.iframe.src);
Android
java
JSONObject param = new JSONObject();
param.put("action","setMusicOpen");
param.put("data",true);
String jsonString = param.toString();
String jsCode = "javascript:DJAndroidBridgeToJs('" + jsonString.replace("'", "\\'") + "')";
iOS
swift
var messageDict: [String: Any] = [
"action": action,
]
if (data != nil) {
messageDict["data"] = data
}
if (callbackId != nil) {
messageDict["callbackId"] = callbackId
}
do {
let jsonData = try JSONSerialization.data(withJSONObject: messageDict, options: [])
if let jsonString = String(data: jsonData, encoding: .utf8) {
let escapedJsonString = jsonString.replacingOccurrences(of: "'", with: "\\'")
evaluateJavaScript(
"window.DJGameToPlatformJs('\(escapedJsonString)')",
completionHandler: { (result, error) in
if let error = error {
print("send message to js error: \(error.localizedDescription)")
}
})
}
} catch {
print("JSON decode error: \(error.localizedDescription)")
}
2J 执行的代码
无返回值的情况
js
// 无返回值的动作
window.DJGameToPlatformJs({
action: "setMusicOpen",
data: true,
});
有返回值的情况
- 请求动作
js
window.DJGameToPlatformJs({
action: "isMusicOpen",
data: null,
// 这里的id需要自行进行处理,每次的请求都需要不一样,避免冲突
callbackId: 1,
});
// 2J 会根据callbackId的请求平台callBackAction
- 响应动作
js
const param = {
action: "callBackAction",
data: {
callbackId: 1,
data: true,
inputAction: "isMusicOpen",
success: true,
},
};
if (android) {
window["DJAndroidBridge"].onMessageReceived(param);
} else if (iOS) {
window.webkit.messageHandlers.DJiOSBridge.postMessage(param);
} else if (iframe) {
window.parent.postMessage(param, "*");
}
2J 发送动作给平台
2J 执行的代码
js
const param = {
action: "xxx",
data: {},
};
if (android) {
window["DJAndroidBridge"].onMessageReceived(param);
} else if (iOS) {
window.webkit.messageHandlers.DJiOSBridge.postMessage(param);
} else if (iframe) {
window.parent.postMessage.postMessage(param, "*");
}
iframe 的方式
js
window.addEventListener("message", (event) => {
if (!this.iframe) {
return;
}
if (
event.origin === new URL(this.iframe.src).origin &&
event.source === this.iframe.contentWindow
) {
const data = event.data;
if (typeof data == "object" && data != null && typeof data.action == "string") {
console.log("%c [Iframe on message]: %o", "color: #90ee90", data);
if (data.action == "callBackAction") {
const taskData = data.data || {};
const callbackId = taskData.callbackId;
const callbackData = taskData.data;
const isSuccess = taskData.success;
// 在这里处理回调的情况
} else {
// 在这里处理其他的动作
}
}
}
});
iOS (Swift) 示例
swift
init(frame: CGRect) {
let userContentController = WKUserContentController()
self.messageHandler = WebViewMessageHandler(delegate: nil)
userContentController.add(self.messageHandler, name: "DJiOSBridge")
config.userContentController = userContentController
self.uiDelegate = self
}
func userContentController(
_ userContentController: WKUserContentController, didReceive message: WKScriptMessage
) {
if message.name == "DJiOSBridge" {
if let body = message.body as? String {
guard let bodyData = body.data(using: .utf8) else { return }
do {
if let jsonDict = try JSONSerialization.jsonObject(with: bodyData, options: []) as? [String: Any] {
let action = jsonDict["action"] as! String
let data = jsonDict["data"]
if action == "callBackAction" {
let recvData = data as! [String: Any]
let callbackId:Int = recvData["callbackId"] as! Int;
let success = recvData["success"] as! Bool
let retData = recvData["data"]
if (success) {
// 动作执行成功
} else {
// 动作执行错误
}
} else {
// onMessageReceived?(action, data)
// 在这里处理其他的动作
}
}
} catch {
print("JSON 解析错误: \(error.localizedDescription)")
}
}
}
}
Android(Java) 示例
java
DJWebViewJsBridge bridge = new DJWebViewJsBridge(messageReceived);
webview.addJavascriptInterface(bridge,"DJAndroidBridge");
@JavascriptInterface
public void onMessageReceived(String jsonStr) {
try {
JSONObject jsonObject = new JSONObject(jsonStr);
String action = (String) jsonObject.get("action");
if (action.equals("callBackAction")) {
JSONObject recvData = jsonObject.getJSONObject("data");
int callbackId = (int) recvData.get("callbackId");
boolean success = (boolean) recvData.get("success");
Object retData = null;
if (!recvData.isNull("data")) {
retData = recvData.get("data");
}
if (success) {
// 动作执行成功
} else {
// 动作执行错误
}
} else {
// 在这里处理其他的动作
}
} catch (JSONException e) {
e.printStackTrace();
}
}