Fix: #32 The rendering process ipc listens for adding a frameId group.

Add a frame object to implement the ipc target.IWindow interface
This commit is contained in:
yanghy 2024-06-23 15:34:51 +08:00
parent 8a7cedb131
commit 70c2fb82e1
7 changed files with 86 additions and 34 deletions

View File

@ -13,6 +13,7 @@
package cef package cef
import ( import (
"fmt"
"github.com/energye/energy/v2/cef/internal/ipc" "github.com/energye/energy/v2/cef/internal/ipc"
"github.com/energye/energy/v2/cef/internal/process" "github.com/energye/energy/v2/cef/internal/process"
"github.com/energye/energy/v2/consts" "github.com/energye/energy/v2/consts"
@ -21,11 +22,12 @@ import (
// 创建应用上下文 - 默认实现 // 创建应用上下文 - 默认实现
func appOnContextCreated(browser *ICefBrowser, frame *ICefFrame, context *ICefV8Context) { func appOnContextCreated(browser *ICefBrowser, frame *ICefFrame, context *ICefV8Context) {
fmt.Println("appOnContextCreated browserId:", browser.Identifier(), " frameId:", frame.Identifier(), "IsMain:", frame.IsMain())
process.Current.SetBrowserId(browser.Identifier()) // 当前进程 browserID process.Current.SetBrowserId(browser.Identifier()) // 当前进程 browserID
process.Current.SetFrameId(frame.Identifier()) // 当前进程 frameId process.Current.SetFrameId(frame.Identifier()) // 当前进程 frameId
ipc.RenderChan().SetRealityChannel(browser.Identifier(), frame.Identifier()) // 设置并更新真实的通道ID ipc.RenderChan().SetRealityChannel(browser.Identifier(), frame.Identifier()) // 设置并更新真实的通道ID
ipcRender.registerGoWaitReplayEvent() // render ipc ipcRender.registerGoWaitReplayEvent() // render ipc
ipcRender.makeIPC(context) // render ipc make ipcRender.makeIPC(frame.Identifier(), context) // render ipc make
makeProcess(browser, frame, context) // process make makeProcess(browser, frame, context) // process make
} }

View File

@ -654,6 +654,7 @@ func init() {
dllimports.NewEnergyImport("CEFBrowser_StopLoad", 0), dllimports.NewEnergyImport("CEFBrowser_StopLoad", 0),
dllimports.NewEnergyImport("CEFBrowser_FrameCount", 0), dllimports.NewEnergyImport("CEFBrowser_FrameCount", 0),
dllimports.NewEnergyImport("CEFBrowser_GetFrameNames", 0), dllimports.NewEnergyImport("CEFBrowser_GetFrameNames", 0),
dllimports.NewEnergyImport("CEFBrowser_GetFrameIdentifiers", 0),
dllimports.NewEnergyImport("CEFBrowser_Find", 0), dllimports.NewEnergyImport("CEFBrowser_Find", 0),
dllimports.NewEnergyImport("CEFBrowser_StopFinding", 0), dllimports.NewEnergyImport("CEFBrowser_StopFinding", 0),
dllimports.NewEnergyImport("CEFBrowser_GetRequestContext", 0), dllimports.NewEnergyImport("CEFBrowser_GetRequestContext", 0),

View File

@ -654,6 +654,7 @@ const (
CEFBrowser_StopLoad CEFBrowser_StopLoad
CEFBrowser_FrameCount CEFBrowser_FrameCount
CEFBrowser_GetFrameNames CEFBrowser_GetFrameNames
CEFBrowser_GetFrameIdentifiers
CEFBrowser_Find CEFBrowser_Find
CEFBrowser_StopFinding CEFBrowser_StopFinding
CEFBrowser_GetRequestContext CEFBrowser_GetRequestContext

View File

@ -52,7 +52,7 @@ var (
ipcBrowser *ipcBrowserProcess // 主进程 IPC ipcBrowser *ipcBrowserProcess // 主进程 IPC
) )
// ipcEmitHandler ipc.emit 处理器 // ipc.emit 处理器
type ipcEmitHandler struct { type ipcEmitHandler struct {
handler *ICefV8Handler // ipc.emit handler handler *ICefV8Handler // ipc.emit handler
handlerSync *ICefV8Handler // ipc.emitSync handler handlerSync *ICefV8Handler // ipc.emitSync handler
@ -61,14 +61,14 @@ type ipcEmitHandler struct {
callbackLock sync.Mutex // ipc.emit lock callbackLock sync.Mutex // ipc.emit lock
} }
// ipcOnHandler ipc.on 处理器 // ipc.on 处理器
type ipcOnHandler struct { type ipcOnHandler struct {
handler *ICefV8Handler // ipc.on handler handler *ICefV8Handler // ipc.on handler
callbackList map[string]*ipcCallback // ipc.on callbackList callbackList map[string]*ipcCallback // ipc.on callbackList
callbackLock sync.Mutex // ipc.emit lock callbackLock sync.Mutex // ipc.emit lock
} }
// ipcCallback ipc.emit 回调结果 // ipc.emit 回调结果
type ipcCallback struct { type ipcCallback struct {
isSync bool //同否同步 true:同步 false:异步, 默认false isSync bool //同否同步 true:同步 false:异步, 默认false
resultType result_type //返回值类型 0:function 1:variable 默认:0 resultType result_type //返回值类型 0:function 1:variable 默认:0
@ -77,7 +77,7 @@ type ipcCallback struct {
name *ICefV8Value //事件名称 name *ICefV8Value //事件名称
} }
// isIPCInternalKey IPC 内部定义使用 key 不允许使用 // IPC 内部定义使用 key 不允许使用
func isIPCInternalKey(key string) bool { func isIPCInternalKey(key string) bool {
return key == internalIPC || key == internalIPCEmit || key == internalIPCOn || key == internalIPCDRAG || key == internalIPCEmitWait || return key == internalIPC || key == internalIPCEmit || key == internalIPCOn || key == internalIPCDRAG || key == internalIPCEmitWait ||
key == internalIPCJSExecuteGoEvent || key == internalIPCJSExecuteGoEventReplay || key == internalIPCJSExecuteGoEvent || key == internalIPCJSExecuteGoEventReplay ||
@ -86,15 +86,15 @@ func isIPCInternalKey(key string) bool {
} }
// ipcInit 初始化 // 初始化
func ipcInit() { func ipcInit() {
isSingleProcess := application.SingleProcess() isSingleProcess := application.SingleProcess()
if isSingleProcess { if isSingleProcess {
ipcBrowser = &ipcBrowserProcess{} ipcBrowser = &ipcBrowserProcess{}
ipcRender = &ipcRenderProcess{ ipcRender = &ipcRenderProcess{
waitChan: &ipc.WaitChan{Pending: new(sync.Map)}, waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)}, emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
onHandler: &ipcOnHandler{callbackList: make(map[string]*ipcCallback)}, onFrameHandler: make(map[int64]*ipcOnHandler),
} }
ipc.CreateBrowserIPC() // Go IPC browser ipc.CreateBrowserIPC() // Go IPC browser
ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render
@ -104,16 +104,16 @@ func ipcInit() {
ipc.CreateBrowserIPC() // Go IPC browser ipc.CreateBrowserIPC() // Go IPC browser
} else if process.Args.IsRender() { } else if process.Args.IsRender() {
ipcRender = &ipcRenderProcess{ ipcRender = &ipcRenderProcess{
waitChan: &ipc.WaitChan{Pending: new(sync.Map)}, waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)}, emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
onHandler: &ipcOnHandler{callbackList: make(map[string]*ipcCallback)}, onFrameHandler: make(map[int64]*ipcOnHandler),
} }
ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render
} }
} }
} }
// addCallback // 添加一个回调函数
func (m *ipcEmitHandler) addCallback(callback *ipcCallback) int32 { func (m *ipcEmitHandler) addCallback(callback *ipcCallback) int32 {
//return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback))) //return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback)))
m.callbackLock.Lock() m.callbackLock.Lock()
@ -122,7 +122,7 @@ func (m *ipcEmitHandler) addCallback(callback *ipcCallback) int32 {
return m.callbackMessageId return m.callbackMessageId
} }
// nextMessageId 获取下一个消息ID // 获取下一个消息ID
func (m *ipcEmitHandler) nextMessageId() int32 { func (m *ipcEmitHandler) nextMessageId() int32 {
m.callbackMessageId++ m.callbackMessageId++
if m.callbackMessageId == -1 { if m.callbackMessageId == -1 {
@ -131,7 +131,7 @@ func (m *ipcEmitHandler) nextMessageId() int32 {
return m.callbackMessageId return m.callbackMessageId
} }
// getCallback 返回回调函数 // 返回回调函数
func (m *ipcEmitHandler) getCallback(messageId int32) *ipcCallback { func (m *ipcEmitHandler) getCallback(messageId int32) *ipcCallback {
//return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback) //return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback)
m.callbackLock.Lock() m.callbackLock.Lock()
@ -143,7 +143,7 @@ func (m *ipcEmitHandler) getCallback(messageId int32) *ipcCallback {
return nil return nil
} }
// clear 清空所有回调函数 // 清空所有回调函数
func (m *ipcEmitHandler) clear() { func (m *ipcEmitHandler) clear() {
for _, v := range m.callbackList { for _, v := range m.callbackList {
v.function.SetCanNotFree(false) v.function.SetCanNotFree(false)
@ -154,7 +154,7 @@ func (m *ipcEmitHandler) clear() {
m.callbackList = make(map[int32]*ipcCallback) m.callbackList = make(map[int32]*ipcCallback)
} }
// addCallback 根据事件名添加回调函数 // 根据事件名添加回调函数
func (m *ipcOnHandler) addCallback(eventName string, callback *ipcCallback) { func (m *ipcOnHandler) addCallback(eventName string, callback *ipcCallback) {
//return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback))) //return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback)))
m.callbackLock.Lock() m.callbackLock.Lock()
@ -168,7 +168,7 @@ func (m *ipcOnHandler) addCallback(eventName string, callback *ipcCallback) {
m.callbackList[eventName] = callback m.callbackList[eventName] = callback
} }
// removeCallback 根据事件名移除回调函数 // 根据事件名移除回调函数
func (m *ipcOnHandler) removeCallback(eventName string) { func (m *ipcOnHandler) removeCallback(eventName string) {
//m.callbackList.Remove((*list.Element)(unsafe.Pointer(ptr))) //m.callbackList.Remove((*list.Element)(unsafe.Pointer(ptr)))
m.callbackLock.Lock() m.callbackLock.Lock()
@ -176,7 +176,7 @@ func (m *ipcOnHandler) removeCallback(eventName string) {
delete(m.callbackList, eventName) delete(m.callbackList, eventName)
} }
// getCallback 根据事件名返回回调函数 // 根据事件名返回回调函数
func (m *ipcOnHandler) getCallback(eventName string) *ipcCallback { func (m *ipcOnHandler) getCallback(eventName string) *ipcCallback {
//return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback) //return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback)
m.callbackLock.Lock() m.callbackLock.Lock()
@ -184,7 +184,7 @@ func (m *ipcOnHandler) getCallback(eventName string) *ipcCallback {
return m.callbackList[eventName] return m.callbackList[eventName]
} }
// clear 清空所有回调函数 // 清空所有回调函数
func (m *ipcOnHandler) clear() { func (m *ipcOnHandler) clear() {
for _, v := range m.callbackList { for _, v := range m.callbackList {
v.function.SetCanNotFree(false) v.function.SetCanNotFree(false)

View File

@ -26,24 +26,27 @@ import (
// ipcRenderProcess 渲染进程 // ipcRenderProcess 渲染进程
type ipcRenderProcess struct { type ipcRenderProcess struct {
isInitRenderIPC bool isInitRenderIPC bool
ipcObject *ICefV8Value // ipc object ipcObject *ICefV8Value // ipc object
emitHandler *ipcEmitHandler // ipc.emit handler emitHandler *ipcEmitHandler // ipc.emit handler
onHandler *ipcOnHandler // ipc.on handler onHandler map[int64]*ipcOnHandler // ipc.on handler
waitChan *ipc.WaitChan waitChan *ipc.WaitChan
} }
func (m *ipcRenderProcess) clear() { func (m *ipcRenderProcess) clear(frameId int64) {
if m.ipcObject != nil { if m.ipcObject != nil {
m.ipcObject.Free() m.ipcObject.Free()
m.ipcObject = nil m.ipcObject = nil
} }
if m.onHandler != nil { if m.onHandler != nil {
m.onHandler.clear() if on, ok := m.onHandler[frameId]; ok {
on.clear()
delete(m.onHandler, frameId)
}
} }
} }
// jsOnEvent JS ipc.on 监听事件 // JS ipc.on 监听事件
func (m *ipcRenderProcess) jsOnEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) { func (m *ipcOnHandler) jsOnEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) {
if name != internalIPCOn { if name != internalIPCOn {
return return
} else if arguments.Size() != 2 { //必须是2个参数 } else if arguments.Size() != 2 { //必须是2个参数
@ -74,13 +77,17 @@ func (m *ipcRenderProcess) jsOnEvent(name string, object *ICefV8Value, arguments
onCallback.SetCanNotFree(true) onCallback.SetCanNotFree(true)
onNameValue = onName.GetStringValue() onNameValue = onName.GetStringValue()
//ipc on //ipc on
m.onHandler.addCallback(onNameValue, &ipcCallback{function: V8ValueRef.UnWrap(onCallback), name: V8ValueRef.UnWrap(onName)}) m.addCallback(onNameValue, &ipcCallback{function: V8ValueRef.UnWrap(onCallback), name: V8ValueRef.UnWrap(onName)})
result = true result = true
return return
} }
// Go ipc.emit 执行JS事件 // Go ipc.emit 执行JS事件
func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) (result bool) { func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) (result bool) {
on, ok := m.onHandler[frame.Identifier()]
if !ok {
return false
}
result = true result = true
argumentListBytes := message.ArgumentList().GetBinary(0) argumentListBytes := message.ArgumentList().GetBinary(0)
//接收二进制数据失败 //接收二进制数据失败
@ -120,7 +127,7 @@ func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICef
} }
}() }()
if callback := ipcRender.onHandler.getCallback(emitName); callback != nil { if callback := on.getCallback(emitName); callback != nil {
var callbackArgsBytes interface{} var callbackArgsBytes interface{}
//enter v8context //enter v8context
ctx := frame.V8Context() ctx := frame.V8Context()
@ -737,10 +744,10 @@ func (m *ipcRenderProcess) ipcJSExecuteGoSyncEventMessageReply(messageId int32,
} }
// ipc // ipc
func (m *ipcRenderProcess) makeIPC(context *ICefV8Context) { func (m *ipcRenderProcess) makeIPC(frameId int64, context *ICefV8Context) {
if m.ipcObject != nil { if m.ipcObject != nil {
// 刷新时释放掉 // 刷新时释放掉
m.clear() m.clear(frameId)
} }
// ipc emit // ipc emit
m.emitHandler.handler = V8HandlerRef.New() m.emitHandler.handler = V8HandlerRef.New()
@ -751,14 +758,24 @@ func (m *ipcRenderProcess) makeIPC(context *ICefV8Context) {
m.emitHandler.handlerSync.Execute(m.jsExecuteGoEvent) m.emitHandler.handlerSync.Execute(m.jsExecuteGoEvent)
// ipc on // ipc on
m.onHandler.handler = V8HandlerRef.New() var on *ipcOnHandler
m.onHandler.handler.Execute(m.jsOnEvent) if handler, ok := m.onHandler[frameId]; ok {
on = handler
} else {
on = &ipcOnHandler{handler: V8HandlerRef.New(), callbackList: make(map[string]*ipcCallback)}
on.handler.Execute(on.jsOnEvent)
m.onHandler[frameId] = on
}
//m.onHandler.handler = V8HandlerRef.New()
//m.onHandler.handler.Execute(m.jsOnEvent)
//on.handler = V8HandlerRef.New()
// ipc object // ipc object
m.ipcObject = V8ValueRef.NewObject(nil) m.ipcObject = V8ValueRef.NewObject(nil)
m.ipcObject.setValueByKey(internalIPCEmit, V8ValueRef.newFunction(internalIPCEmit, m.emitHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY) m.ipcObject.setValueByKey(internalIPCEmit, V8ValueRef.newFunction(internalIPCEmit, m.emitHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
m.ipcObject.setValueByKey(internalIPCEmitWait, V8ValueRef.newFunction(internalIPCEmitWait, m.emitHandler.handlerSync), consts.V8_PROPERTY_ATTRIBUTE_READONLY) m.ipcObject.setValueByKey(internalIPCEmitWait, V8ValueRef.newFunction(internalIPCEmitWait, m.emitHandler.handlerSync), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
m.ipcObject.setValueByKey(internalIPCOn, V8ValueRef.newFunction(internalIPCOn, m.onHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY) m.ipcObject.setValueByKey(internalIPCOn, V8ValueRef.newFunction(internalIPCOn, on.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
// ipc key to v8 global // ipc key to v8 global
context.Global().setValueByKey(internalIPC, m.ipcObject, consts.V8_PROPERTY_ATTRIBUTE_READONLY) context.Global().setValueByKey(internalIPC, m.ipcObject, consts.V8_PROPERTY_ATTRIBUTE_READONLY)

View File

@ -520,6 +520,15 @@ func (m *ICefBrowser) GetFrameNames() []*FrameNames {
return frameNames return frameNames
} }
func (m *ICefBrowser) GetFrameIdentifiers() []int64 {
var list uintptr
var count uint32
var ids uintptr
imports.Proc(def.CEFBrowser_GetFrameIdentifiers).Call(m.Instance(), uintptr(unsafe.Pointer(&list)), uintptr(unsafe.Pointer(&count)), uintptr(unsafe.Pointer(&ids)))
// TODO 未取到正确结果
return nil
}
// Find 检索页面文本 // Find 检索页面文本
func (m *ICefBrowser) Find(searchText string, forward, matchCase, findNext bool) { func (m *ICefBrowser) Find(searchText string, forward, matchCase, findNext bool) {
if !m.IsValid() { if !m.IsValid() {

View File

@ -264,6 +264,28 @@ func (m *ICefFrame) Parent() *ICefFrame {
return &ICefFrame{instance: unsafe.Pointer(result)} return &ICefFrame{instance: unsafe.Pointer(result)}
} }
func (m *ICefFrame) Target(targetType ...target.Type) target.ITarget {
if !m.IsValid() {
return nil
}
browse := m.Browser()
if !browse.IsValid() {
return nil
}
return target.NewTarget(m, browse.Identifier(), m.Identifier(), targetType...)
}
func (m *ICefFrame) IsClosing() bool {
return false //Determine whether the window has been closed by oneself
}
func (m *ICefFrame) ProcessMessage() target.IProcessMessage {
if m == nil {
return nil
}
return m
}
func (m *ICefFrame) Free() { func (m *ICefFrame) Free() {
if !m.IsValid() { if !m.IsValid() {
return return