介绍
Energy Go和JS的事件通信, Go监听事件JS触发。
IPC事件还有其它的几种使用方式,在其它教程中更新
在正常前后端大多数开发场景,JS和Go前后端数据交互都需要Http接口方式交互。
Energy中可以不使用Http,使用事件通信机制(IPC),事件通信可以让Go和JS很方便的进行数据交互和功能实现,在Go中或JS定义事件监听,然后在Go中和JS中触发监听的事件。
定义的方式为
Go: 监听事件 event.On
JS : 触发事件 ipc.emit
使用
Go监听事件
在main函数中
回调函数中监听事件 ipc.IPC.Browser().SetOnEvent(func(event ipc.IEventOn)
监听事件 event.On("事件名", func(context ipc.IIPCContext))
context
获取触发的browserId(浏览器ID),channelId(通道ID),获取参数和返回参数
Connect() net.Conn //IPC 链接 EventId() int32 //IPC 事件ID ChannelId() int64 //render channel channelId BrowserId() int32 //render channel browserId Message() *IPCEventMessage //接收的消息数据 一搬配合Response函数 Response(data []byte) //通过响应应达的方式返回结果,在data符合[argumentList]规范可使用Arguments() 一搬配合Message函数 Free() //释放内存 Arguments() IArgumentList //用于 ipc 进程之间通信, 带有参数类型 Result() *IPCContextResult //用于 render(js)进程触发 browser(go)进程监听返回值, 带有固定几个参数类型
常用的
ChannelId() int64
BrowserId() int32
Arguments() IArgumentList
Result() *IPCContextResult
其它的根据场景而定
Js触发事件
ipc.emit("事件名", [传递参数], [callback])
emit参数
-
参数一,必选: 事件名
-
参数二,可选: 传递参数,数组类型, 示例: ["传递的参数1", "传递的参数2", 666, 888.99, false, true]
-
参数三,可选: 回调函数,带有一个返回参数
function writeMessage(data) { let message = document.getElementById("message"); message.innerHTML = message.innerHTML + data + "<br>" }ipc.emit('go-on-event-demo-return', ['传递的数据', 99999, false, 9999.999], function (data) { writeMessage("data-length: " + data.length) writeMessage("data: " + data) })
完整示例
Go
package main
import (
"bytes"
"embed"
"fmt"
"github.com/energye/energy/cef"
"github.com/energye/energy/common/assetserve"
"github.com/energye/energy/ipc"
"strings"
)
//go:embed resources
var resources embed.FS
func main() {
//全局初始化 每个应用都必须调用的
cef.GlobalCEFInit(nil, &resources)
//创建应用
cefApp := cef.NewApplication(nil)
//指定一个URL地址,或本地html文件目录
cef.BrowserWindow.Config.DefaultUrl = "http://localhost:22022/go-to-js.html"
cef.BrowserWindow.Config.Title = "Energy - go on event - js emit event"
cef.BrowserWindow.Config.Icon = "resources/icon.ico"
ipc.IPC.Browser().SetOnEvent(func(event ipc.IEventOn) {
//在go中监听一个事件
event.On("go-on-event-demo", func(context ipc.IIPCContext) {
fmt.Println("go-on-event-demo event run")
//js 中传递的数据
//虽然 Arguments 结构支持多个数据类型,但在js和go的对应中,只保留了 string, integer, double, boolean 的对应关系,其它类型在 go 和 js数据传递时不支持
arguments := context.Arguments()
fmt.Println("参数个数:", arguments.Size())
//参数是以js调用时传递的参数下标位置开始计算,从0开始表示第1个参数
p1 := arguments.GetString(0)
fmt.Println("参数1:", p1)
})
//带有返回值的事件
event.On("go-on-event-demo-return", func(context ipc.IIPCContext) {
fmt.Println("go-on-event-demo-return event run")
//js 中传递的数据
//虽然 Arguments 结构支持多个数据类型,但在js和go的对应中,只保留了 string, integer, double, boolean 的对应关系,其它类型在 go 和 js数据传递时不支持
arguments := context.Arguments()
fmt.Println("参数个数:", arguments.Size())
//参数是以js调用时传递的参数下标位置开始计算,从0开始表示第1个参数
p1 := arguments.GetString(0)
p2 := arguments.GetInt32(1)
p3 := arguments.GetBool(2)
p4 := arguments.GetFloat64(3)
fmt.Println("\t参数1-length:", len(p1))
//fmt.Println("\t参数1:", p1)
fmt.Println("\t参数2:", p2)
fmt.Println("\t参数3:", p3)
fmt.Println("\t参数4:", p4)
//返回给JS数据, 通过 context.Result()
var buf = bytes.Buffer{}
for i := 0; i < 100000; i++ {
buf.WriteString(fmt.Sprintf("[%d]-", i))
}
var data = "这是在GO中监听事件返回给JS的数据:" + buf.String()
fmt.Println("返回给JS数据 - length:", strings.Count(data, "")-1)
context.Result().SetString(data)
})
})
//内置http服务链接安全配置
cef.SetBrowserProcessStartAfterCallback(func(b bool) {
fmt.Println("主进程启动 创建一个内置http服务")
//通过内置http服务加载资源
server := assetserve.NewAssetsHttpServer()
server.PORT = 22022
server.AssetsFSName = "resources" //必须设置目录名
server.Assets = &resources
go server.StartHttpServer()
})
//运行应用
cef.Run(cefApp)
}
JS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>go-to-js</title>
<script type="application/javascript">
function clearMessage() {
document.getElementById("message").innerHTML = "";
}
function writeMessage(data) {
let message = document.getElementById("message");
message.innerHTML = message.innerHTML + data + "<br>"
}
//ipc.emit函数有3个参数
//参数1 事件名 必填 string类型
//参数2 参数 非必填 array类型,传递到Go中的数据,
// 参数只保留了 string, integer, double, boolean 的对应关系,其它类型在 go和 js数据传递时不支持
// 参数是以js调用时传递的参数下标位置开始计算,从0开始表示第1个参数
//参数3 回调函数 非必填 function类型, go返回的结果
//调用Go中监听的事件
function goOnEventDemo() {
clearMessage()
//参数传递,从下标0开始表示第1个参数
ipc.emit('go-on-event-demo', ['传递的数据'])
}
//带有返回值的事件
function goOnEventDemoReturn() {
clearMessage()
//参数传递,从下标0开始表示第1个参数
var strData = ""
for (var i = 0; i < 100000; i++) {
strData += "[" + i + "]";
}
ipc.emit('go-on-event-demo-return', ['传递的数据:' + strData, 99999, false, 9999.999], function (data) {
writeMessage("data-length: " + data.length)
writeMessage("data: " + data)
})
}
</script>
</head>
<body style="margin: 0px;padding: 0px;">
Go中监听事件,JS中调用<br>
<button onclick="goOnEventDemo()">go-on-event-demo</button>
<button onclick="goOnEventDemoReturn()">go-on-event-demo-return</button>
<div id="message"></div>
</body>
</html>
效果图