energy/ipc/cef-ipc-render.go

217 lines
5.5 KiB
Go
Raw Normal View History

2022-10-04 13:21:05 +08:00
//----------------------------------------
//
// Copyright © yanghy. All Rights Reserved.
//
2022-10-04 16:38:43 +08:00
// Licensed under GNU General Public License v3.0
2022-10-04 13:21:05 +08:00
//
//----------------------------------------
2022-10-04 22:34:57 +08:00
package ipc
2022-10-04 13:21:05 +08:00
import (
"fmt"
2022-10-04 22:34:57 +08:00
. "github.com/energye/energy/commons"
. "github.com/energye/energy/consts"
"github.com/energye/energy/logger"
2022-10-04 13:21:05 +08:00
"net"
"sync"
)
type renderChannel struct {
2022-10-04 22:34:57 +08:00
msgID *MsgID
2022-10-04 13:21:05 +08:00
browserId int32
channelId int64 //render channel Id
ipcType IPC_TYPE
2022-10-30 00:35:04 +08:00
connect net.Conn
2022-10-04 13:21:05 +08:00
mutex sync.Mutex
events *event
2022-10-04 22:34:57 +08:00
emitCallback *EmitCallbackCollection
emitSync map[string]*EmitSyncCollection
2022-10-04 13:21:05 +08:00
renderOnEvents []func(browseProcess IEventOn)
renderEmitCallback []func(renderProcess IEventEmit)
isConnect bool
}
// 触发事件回调函数集合
2022-10-04 22:34:57 +08:00
type EmitCallbackCollection struct {
EmitCollection sync.Map
2022-10-04 13:21:05 +08:00
}
// 触发同步事件集合
2022-10-04 22:34:57 +08:00
type EmitSyncCollection struct {
Mutex *sync.Mutex
EmitCollection sync.Map
2022-10-04 13:21:05 +08:00
}
func (m *ipcChannel) newRenderChannel(memoryAddresses ...string) {
if UseNetIPCChannel {
2022-10-18 10:12:56 +08:00
address := fmt.Sprintf("localhost:%d", IPC.Port())
2022-10-04 13:21:05 +08:00
conn, err := net.Dial("tcp", address)
if err != nil {
panic("Client failed to connect to IPC service Error: " + err.Error())
}
m.render.ipcType = IPCT_NET
2022-10-30 00:35:04 +08:00
m.render.connect = conn
2022-10-04 13:21:05 +08:00
} else {
memoryAddr := ipcSock
if len(memoryAddresses) > 0 {
memoryAddr = memoryAddresses[0]
}
2022-10-04 22:34:57 +08:00
unixAddr, err := net.ResolveUnixAddr(MemoryNetwork, memoryAddr)
2022-10-04 13:21:05 +08:00
if err != nil {
panic("Client failed to connect to IPC service Error: " + err.Error())
}
2022-10-04 22:34:57 +08:00
unixConn, err := net.DialUnix(MemoryNetwork, nil, unixAddr)
2022-10-04 13:21:05 +08:00
if err != nil {
panic("Client failed to connect to IPC service Error: " + err.Error())
}
m.render.ipcType = IPCT_UNIX
2022-10-30 00:35:04 +08:00
m.render.connect = unixConn
2022-10-04 13:21:05 +08:00
}
go m.render.receive()
}
2022-10-04 22:34:57 +08:00
func (m *EmitCallbackCollection) remove(key int32) {
m.EmitCollection.Delete(key)
2022-10-04 13:21:05 +08:00
}
2022-10-04 22:34:57 +08:00
func (m *renderChannel) Events() *event {
return m.events
}
func (m *renderChannel) Channel(channelId int64) *channel {
return nil
}
func (m *renderChannel) Close() {
2022-10-30 00:35:04 +08:00
if m.connect != nil {
m.connect.Close()
m.connect = nil
2022-10-04 13:21:05 +08:00
}
m.isConnect = false
}
// IPC render 设置监听初始化回调
func (m *renderChannel) SetOnEvent(callback func(event IEventOn)) {
if Args.IsRender() || SingleProcess {
m.renderOnEvents = append(m.renderOnEvents, callback)
}
}
func (m *renderChannel) call(name string, context IIPCContext) bool {
2022-10-04 22:34:57 +08:00
callBack := m.events.Get(name)
2022-10-04 13:21:05 +08:00
if callBack != nil {
callBack(context)
return true
}
return false
}
func (m *renderChannel) On(name string, eventCallback EventCallback) {
m.events.add(name, eventCallback)
}
func (m *renderChannel) Emit(eventName string, arguments IArgumentList) {
if m.conn() == nil {
return
}
m.mutex.Lock()
defer m.mutex.Unlock()
if arguments == nil {
arguments = NewArgumentList()
}
2022-10-04 22:34:57 +08:00
ipcWrite(Tm_Async, m.channelId, m.msgID.New(), []byte(eventName), arguments.Package(), m.conn())
2022-10-04 13:21:05 +08:00
}
2022-10-04 22:34:57 +08:00
func (m *renderChannel) EmitAndCallback(eventName string, arguments IArgumentList, callback IPCCallback) {
2022-10-04 13:21:05 +08:00
if m.conn() == nil {
return
}
m.mutex.Lock()
defer m.mutex.Unlock()
if arguments == nil {
arguments = NewArgumentList()
}
2022-10-04 22:34:57 +08:00
eventId := m.msgID.New()
m.emitCallback.EmitCollection.Store(eventId, callback)
ipcWrite(Tm_Callback, m.channelId, eventId, []byte(eventName), arguments.Package(), m.conn())
2022-10-04 13:21:05 +08:00
}
func (m *renderChannel) EmitAndReturn(eventName string, arguments IArgumentList) IIPCContext {
if m.conn() == nil {
return nil
}
m.mutex.Lock()
defer m.mutex.Unlock()
2022-10-04 22:34:57 +08:00
var emit = func(emitAsync *EmitSyncCollection) IIPCContext {
emitAsync.Mutex.Lock()
defer emitAsync.Mutex.Unlock()
eventId := m.msgID.New()
2022-10-04 13:21:05 +08:00
var chn = make(chan IIPCContext)
2022-10-04 22:34:57 +08:00
emitAsync.EmitCollection.Store(eventId, chn)
ipcWrite(Tm_Sync, m.channelId, eventId, []byte(eventName), arguments.Package(), m.conn())
2022-10-04 13:21:05 +08:00
return <-chn
}
if arguments == nil {
arguments = NewArgumentList()
}
if emitAsync, ok := m.emitSync[eventName]; ok {
return emit(emitAsync)
} else {
2022-10-04 22:34:57 +08:00
m.emitSync[eventName] = &EmitSyncCollection{Mutex: new(sync.Mutex), EmitCollection: sync.Map{}}
2022-10-04 13:21:05 +08:00
return emit(m.emitSync[eventName])
}
}
func (m *renderChannel) conn() net.Conn {
2022-10-30 00:35:04 +08:00
return m.connect
2022-10-04 13:21:05 +08:00
}
func (m *renderChannel) emitConnect() {
args := NewArgumentList()
args.SetString(0, "-connecting")
2022-10-04 22:34:57 +08:00
m.Emit(Ln_onConnectEvent, args)
2022-10-04 13:21:05 +08:00
m.isConnect = true
}
func (m *renderChannel) receive() {
defer func() {
if err := recover(); err != nil {
logger.Error("IPC Render Channel Recover:", err)
}
2022-10-04 22:34:57 +08:00
m.Close()
2022-10-04 13:21:05 +08:00
}()
var readHandler = &ipcReadHandler{
browserId: m.browserId,
channelId: m.channelId,
2022-10-04 22:34:57 +08:00
ct: Ct_Client,
2022-10-04 13:21:05 +08:00
ipcType: m.ipcType,
2022-10-30 00:35:04 +08:00
connect: m.connect,
2022-10-04 13:21:05 +08:00
handler: func(ctx *IPCContext) {
if m.call(ctx.eventName, ctx) {
2022-10-04 22:34:57 +08:00
if (ctx.triggerMode == Tm_Callback || ctx.triggerMode == Tm_Sync) && !ctx.isReply {
2022-10-04 13:21:05 +08:00
ctx.Response([]byte{})
}
} else {
2022-10-04 22:34:57 +08:00
if ctx.triggerMode == Tm_Callback { //回调函数
2022-10-04 13:21:05 +08:00
m.mutex.Lock()
defer m.mutex.Unlock()
2022-10-04 22:34:57 +08:00
if callback, ok := m.emitCallback.EmitCollection.Load(ctx.eventId); ok {
callback.(IPCCallback)(ctx)
m.emitCallback.EmitCollection.Delete(ctx.eventId)
2022-10-04 13:21:05 +08:00
}
2022-10-04 22:34:57 +08:00
} else if ctx.triggerMode == Tm_Sync { //同步调用
2022-10-04 13:21:05 +08:00
if emitAsync, ok := m.emitSync[ctx.eventName]; ok {
2022-10-04 22:34:57 +08:00
if chn, ok := emitAsync.EmitCollection.Load(ctx.eventId); ok {
2022-10-04 13:21:05 +08:00
var c = chn.(chan IIPCContext)
c <- ctx
close(c)
2022-10-04 22:34:57 +08:00
emitAsync.EmitCollection.Delete(ctx.eventId)
2022-10-04 13:21:05 +08:00
}
}
}
}
},
}
ipcRead(readHandler)
}