IPC 事件驱动 
IPC 事件 
它是基于CEF进程消息和Go自定义协议组合实现
CEF进程消息: Application 和 Chromium 的
OnProcessMessageReceived事件Application 处理渲染进程消息
Chromium 处理主进程消息
Go自定义协议: 在Go与Go代码之间消息传递时使用
在 Application OnContextCreated 事件执行时注入 ipc JavaScript 对象到浏览器, 它绑定了 on 和 emit 函数, 在每一个浏览器创建后都会注入ipc
使用方式 
在Go中定义事件 
使用 ipc.On(name string, fn interface{}, options ...types.OnOptions) 注册监听一个事件
- name: 事件名
 - fn: 回调函数, 该事件被触发时执行的函数
 - options: 监听选项, 它提供了2种监听模式,和3种监听类型
 
fn 回调函数 
它可以接收参数和返回数据. 提供了几种自动识别的参数类型。
- context.IContext: 当前事件被执行时原始的事件上下文,在这里可以直接取事件信息
 
go
// IContext
//	Inter process IPC communication callback context
type IContext interface {
	ArgumentList() json.JSONArray //ArgumentList
	BrowserId() int32             //Event ownership: browser id
	FrameId() int64               //Event ownership: frame id
	Replay() IReplay              //Replay, When the trigger event returns IContext, this field is nil
	Result(data ...interface{})   //callback function return Result
}- callback.IChannel: 当前事件被执行时, 该参数类型可自动识别当前事件是从哪一个浏览器触发, 它可以拿到指定的
BrowserId和ChannelId 
go
// IChannel
//
//	The channel ID of the parameter type callback function
//	Used for listening to events and receiving parameters from the event channel source
type IChannel interface {
	BrowserId() int32 //Receive Browser Window ID
	ChannelId() int64 //Receive Channel ID
}- Go和JS的基础和复合类型对应 常用的基础类型和结构
 
options 监听选项 
go
// OnOptions Listening options
type OnOptions struct {
	OnType OnType // Listening type, default main process
	Mode   Mode   // IPC emit mode of the browser process
}监听选项-监听类型 
go
// OnType listening type
type OnType int8
const (
	OtMain OnType = iota // Only the main process
	OtSub                // Only the sub process
	OtAll                // All process
)监听选项-监听模式 
go
// Mode IPC mode of the browser process
type Mode = int8
const (
	// MSync Synchronization, the default way CEF is used
	//  In JS, ipc.emit triggers the Go event and processes long-term tasks. The window will remain frozen until the task processing is completed.
	MSync Mode = iota
	// MAsync
	//  Asynchronous, using coroutines, coroutines (within the event) cannot be debugged, there are no other unforeseen problems found so far.
	//  异步 (Asynchronous): Refers to an approach where operations can continue without waiting for the previous operations' completion.
	//  使用协程 (using coroutines): Indicates the implementation or employment of coroutines, which are a way to manage the execution flow in a non-preemptive manner.
	//  协程(事件内)无法Debug (coroutines (within the event) cannot be debugged): Points out the inability to debug coroutines when they are inside an event.
	//  暂未发现其它无法预料的问题 (there are no other unforeseen problems found so far): Indicates that, at the time of the statement, no other unforeseen issues have been encountered or identified.
	//
	// 使用场景 (Usage scenarios):
	//
	//  Only applicable when using JS ipc.emit to trigger events.
	//  Recommended for use in the Go UI main thread when performing long-duration tasks, otherwise it will freeze the UI window.
	MAsync
)在JS中定义事件 
使用 ipc.on(name: string, fn: function) 注册监听一个事件
- name: 事件名
 - fn: 回调函数, 该事件被触发时执行的函数
 
fn 回调函数 
它可以接收参数和返回数据. 参数类型为常用的基础类型和复合类型(JSON or Array)
在Go中触发JS事件 
在Go有4种触发方式, 都是异步执行, 默认触发主浏览器
ipc.Emit(name string, argument ...interface{}) boolipc.EmitAndCallback(name string, argument []interface{}, callback interface{}) boolipc.EmitTarget(name string, target target.ITarget, argument ...interface{}) boolipc.EmitTargetAndCallback(name string, target target.ITarget, argument []interface{}, callback interface{}) bool
参数 
- name: JS监听的事件名
 - argument: JS监听的回调函数参数,需要注意参数类型
 - callback: 触发回调函数,在JS里如果有返回值可通过该函数获取, 该函数没有返回值
 - target: 触发事件接收目标, 接口类型, 当事件触发目标不是主浏览器时,通过该参数将事件触发给指定浏览器
 
ITarget 
go
// ITarget
//
// ipc.NewTarget() *Target
type ITarget interface {
	BrowserId() int32 // Browser Window ID
	ChannelId() int64 // IPC channelID, frameId or GO IPC channelID
	TargetType() Type // Target type default 0: Trigger JS event
	Window() IWindow  // Send IPC Chromium
}它有几个已实现接口结构 -. LCLBrowserWindow -. ViewsFrameworkBrowserWindow -. TCEFChromium -. ICefFrame 除此之外还可以通过已实现的结构 Target(targetType ...target.Type) 函数定义接收类型.
ITarget 它可以控制事件消息发送位置
go
// Type
//
//	0: Trigger the JS event of the specified target process
//	1: Trigger TgGoSub events for the specified target sub process
//	2: Trigger TgGoMain events for the specified target main process
type Type int8
const (
	TgJs     Type = iota //JS Event
	TgGoSub              //GO Event sub
	TgGoMain             //GO Event main
)go
在JS中触发Go事件 
有2种方式
ipc.emit(name, argument: array, callback: function)ipc.emit({name:string, arguments: array, callback: function, mode: int, target: int})
参数 
- name: 被触发事件名
 - argument: 可选,要传递的参数
 - callback: 可选,触发后回调函数,它可接收Go的返回值
 - mode: 可选,触发模式
 
text
0: 异步 
1: 同步
default 0- target: 可选,触发接收目标,需要和Go的监听配合使用,默认是主进程
 
text
0: 主进程 
1: 当前进程
2: 其它进程(需要主进程)
default 0js
let userData = {"key1":{"Name":"张三1","Age":66,"Income":99988.0009,"Sex":true,"UserInfo":{"Addr":"addr","HeadPicture":"https://www.demo.com/head.png","Height":800,"Weight":800,"Phone":"888-999-000"}},"zhangsan-2":{"Sex":true,"UserInfo":{"HeadPicture":"https://www.demo.com/head.png","Height":800,"Weight":800,"Phone":"888-999-000","Addr":"银河系-猎户座旋臂(离中心远,离边缘近)-太阳系第三环总体位置,离银棒(中心)"},"Name":"张三2","Age":66,"Income":99988.0009},"zhangsan-3":{"Sex":true,"UserInfo":{"Addr":"银河系-猎户座旋臂(离中心远,离边缘近)-太阳系第三环总体位置,离银棒(中心)","HeadPicture":"https://www.demo.com/head.png","Height":800,"Weight":800,"Phone":"888-999-000"},"Name":"张三3","Age":66,"Income":99988.0009}}
ipc.emit('setUserInfo', [userData], function (data) {
   
})
ipc.emit({
    name: "name",
    arguments: ["energy"], 
    callback: function (data) { 
       
    },
    mode: 0, 
    target: 0
})