energy/cef/cef-ipc-browser.go
2023-03-25 12:09:00 +08:00

198 lines
6.0 KiB
Go

//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
// Licensed under Apache License Version 2.0, January 2004
//
// https://www.apache.org/licenses/LICENSE-2.0
//
//----------------------------------------
// energy 主进程 IPC
package cef
import (
"github.com/energye/energy/cef/ipc"
"github.com/energye/energy/consts"
"github.com/energye/energy/pkgs/json"
)
// ipcBrowserProcess 主进程
type ipcBrowserProcess struct {
}
// ipcGoExecuteMethodMessage 执行 Go 监听函数
func (m *ipcBrowserProcess) jsExecuteGoMethodMessage(browser *ICefBrowser, frame *ICefFrame, message *ICefProcessMessage) (result bool) {
argumentListBytes := message.ArgumentList().GetBinary(0)
if argumentListBytes == nil {
return
}
result = true
var messageDataBytes []byte
if argumentListBytes.IsValid() {
size := argumentListBytes.GetSize()
messageDataBytes = make([]byte, size)
c := argumentListBytes.GetData(messageDataBytes, 0)
argumentListBytes.Free() //立即释放掉
if c == 0 {
result = false
return
}
}
var messageId int32
var emitName string
var argument json.JSON
var argumentList json.JSONArray
if messageDataBytes != nil {
argument = json.NewJSON(messageDataBytes)
messageId = int32(argument.GetIntByKey(ipc_id))
emitName = argument.GetStringByKey(ipc_event)
argumentList = argument.GetArrayByKey(ipc_argumentList)
messageDataBytes = nil
}
defer func() {
if argumentList != nil {
argumentList.Free()
}
if argument != nil {
argument.Free()
}
}()
argumentListBytes = nil
var ipcContext = m.jsExecuteGoMethod(browser.Identifier(), frame.Identifier(), emitName, argumentList)
if messageId != 0 { // 异步回调函数处理
replyMessage := json.NewJSONArray(nil)
replyMessage.Add(messageId)
replyMessage.Add(false)
if ipcContext != nil {
//处理回复消息
replay := ipcContext.Replay()
if replay.Result() != nil && len(replay.Result()) > 0 {
switch replay.Result()[0].(type) {
case []byte:
replyMessage.SetByIndex(1, true)
replyMessage.Add((replay.Result()[0]).([]byte))
}
}
}
frame.SendProcessMessageForJSONBytes(internalIPCJSExecuteGoEventReplay, consts.PID_RENDER, replyMessage.Bytes())
replyMessage.Free()
}
if ipcContext != nil {
if ipcContext.ArgumentList() != nil {
ipcContext.ArgumentList().Free()
}
ipcContext.Result(nil)
}
return
}
// jsExecuteGoMethod 执行Go函数
func (m *ipcBrowserProcess) jsExecuteGoMethod(browserId int32, frameId int64, emitName string, argumentList json.JSONArray) ipc.IContext {
eventCallback := ipc.CheckOnEvent(emitName)
var ipcContext ipc.IContext
if eventCallback != nil {
ipcContext = ipc.NewContext(browserId, frameId, true, argumentList)
//调用监听函数
if ctxCallback := eventCallback.ContextCallback(); ctxCallback != nil {
ctxCallback.Invoke(ipcContext)
} else if argsCallback := eventCallback.ArgumentCallback(); argsCallback != nil {
argsCallback.Invoke(ipcContext)
}
}
return ipcContext
}
// ipcGoExecuteMethodMessageReply 执行Go函数回复结果
func (m *ipcBrowserProcess) ipcGoExecuteMethodMessageReply(browser *ICefBrowser, frame *ICefFrame, message *ICefProcessMessage) (result bool) {
argumentListBytes := message.ArgumentList().GetBinary(0)
if argumentListBytes == nil {
return
}
result = true
var messageDataBytes []byte
if argumentListBytes.IsValid() {
size := argumentListBytes.GetSize()
messageDataBytes = make([]byte, size)
c := argumentListBytes.GetData(messageDataBytes, 0)
argumentListBytes.Free()
message.Free()
if c == 0 {
return
}
}
var messageId int32
var argument json.JSON
var argumentList json.JSONArray
if messageDataBytes != nil {
argument = json.NewJSON(messageDataBytes)
messageId = int32(argument.GetIntByKey(ipc_id))
argumentList = argument.GetArrayByKey(ipc_argumentList)
messageDataBytes = nil
}
defer func() {
if argument != nil {
argument.Free()
}
}()
if callback := ipc.CheckEmitCallback(messageId); callback != nil {
ipcContext := ipc.NewContext(browser.Identifier(), frame.Identifier(), false, argumentList)
if ctxCallback := callback.ContextCallback(); ctxCallback != nil {
ctxCallback.Invoke(ipcContext)
} else if argsCallback := callback.ArgumentCallback(); argsCallback != nil {
argsCallback.Invoke(ipcContext)
}
if ipcContext.ArgumentList() != nil {
ipcContext.ArgumentList().Free()
}
ipcContext.Result(nil)
}
return
}
// ipcChannelBrowser Go IPC 主进程监听
func (m *ipcBrowserProcess) initBrowserIPC() {
browserIPC.addCallback(func(channelId int64, data json.JSON) bool {
if data != nil && data.IsObject() {
messageJSON := data.JSONObject()
//messageId := messageJSON.GetIntByKey(ipc_id)// messageId: 同步永远是1
emitName := messageJSON.GetStringByKey(ipc_event)
name := messageJSON.GetStringByKey(ipc_name)
browserId := messageJSON.GetIntByKey(ipc_browser_id)
argumentList := messageJSON.GetArrayByKey(ipc_argumentList)
if name == internalIPCJSExecuteGoSyncEvent {
m.jsExecuteGoSyncMethodMessage(int32(browserId), channelId, emitName, argumentList)
return true
}
}
return false
})
}
// jsExecuteGoSyncMethodMessage JS执行Go事件 - 同步消息处理
func (m *ipcBrowserProcess) jsExecuteGoSyncMethodMessage(browserId int32, frameId int64, emitName string, argumentList json.JSONArray) {
var ipcContext = m.jsExecuteGoMethod(browserId, frameId, emitName, argumentList)
message := NewIPCProcessMessage(1, 0, internalIPCJSExecuteGoSyncEventReplay, "", nil)
// 同步回调函数处理
if ipcContext != nil {
//处理回复消息
replay := ipcContext.Replay()
if replay.Result() != nil && len(replay.Result()) > 0 {
switch replay.Result()[0].(type) {
case []byte:
message.Set(ipc_argumentList, json.NewJSONArray((replay.Result()[0]).([]byte)).Data())
}
}
}
//回复结果消息
browserIPC.ipc.Send(frameId, message.Bytes())
message.Free()
if ipcContext != nil {
if ipcContext.ArgumentList() != nil {
ipcContext.ArgumentList().Free()
}
ipcContext.Result(nil)
}
}