在Go中使用Energy创建跨平台GUI应用 - 事件通信(IPC) 之 Go定义事件JS调用

snxamdf · · 1783 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

​ ### 介绍 > Go和JS的IPC事件通信, Go|JS监听事件, JS|GO触发事件。 > 在正常前后端大多数开发场景,JS和Go前后端数据交互都需要Http接口方式交互。 > Energy中可以不使用Http,使用事件通信机制(IPC),事件通信可以让Go和JS很方便的进行数据交互和功能实现,在Go中或JS定义事件监听,然后在Go中和JS中触发监听的事件。 > 定义方式 ```go Go: 监听事件 ipc.On, 触发事件ipc.Emit JS : 监听事件 ipc.on, 触发事件 ipc.emit ``` 完整示例 ```go package main import ( "bytes" "embed" "fmt" "github.com/energye/energy/v2/cef" "github.com/energye/energy/v2/cef/ipc" "github.com/energye/energy/v2/cef/ipc/context" "github.com/energye/energy/v2/common" "github.com/energye/energy/v2/pkgs/assetserve" "strings" ) //go:embed resources var resources embed.FS func main() { //全局初始化 每个应用都必须调用的 cef.GlobalInit(nil, &resources) //创建应用 cefApp := cef.NewApplication() //指定一个URL地址,或本地html文件目录 cef.BrowserWindow.Config.Url = "http://localhost:22022/go-to-js.html" cef.BrowserWindow.Config.Title = "Energy - go on event - js emit event" if common.IsLinux() { cef.BrowserWindow.Config.IconFS = "resources/icon.png" } else { cef.BrowserWindow.Config.IconFS = "resources/icon.ico" } //在go中监听一个事件, 不带返回值 //使用上下文获取参数 ipc.On("go-on-event-demo", func(context context.IContext) { fmt.Println("go-on-event-demo event run") //js 中传递的数据 //虽然 Arguments 结构支持多个数据类型,但在js和go的对应中,只保留了 string, integer, double, boolean 的对应关系,其它类型在 go 和 js数据传递时不支持 arguments := context.ArgumentList() fmt.Println("参数个数:", arguments.Size()) //参数是以js调用时传递的参数下标位置开始计算,从0开始表示第1个参数 p1 := arguments.GetStringByIndex(0) fmt.Println("参数1:", p1) }) //带有返回值的事件 //使用上下文获取参数 ipc.On("go-on-event-demo-return", func(context context.IContext) { fmt.Println("go-on-event-demo-return event run") //js 中传递的数据 //虽然 Arguments 结构支持多个数据类型,但在js和go的对应中,只保留了 string, integer, double, boolean 的对应关系,其它类型在 go 和 js数据传递时不支持 arguments := context.ArgumentList() fmt.Println("参数个数:", arguments.Size()) //参数是以js调用时传递的参数下标位置开始计算,从0开始表示第1个参数 p1 := arguments.GetStringByIndex(0) p2 := arguments.GetIntByIndex(1) p3 := arguments.GetBoolByIndex(2) p4 := arguments.GetFloatByIndex(3) p5 := arguments.GetStringByIndex(4) fmt.Println("\t参数1-length:", len(p1), p1) //fmt.Println("\t参数1:", p1) fmt.Println("\t参数2:", p2) fmt.Println("\t参数3:", p3) fmt.Println("\t参数4:", p4) fmt.Println("\t参数5:", p5) //返回给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(data) }) // 在Go中监听一个事件, 不带返回值 // 使用形参接收参数 // 在JS中入参类型必须相同 ipc.On("go-on-event-demo-argument", func(param1 int, param2 string, param3 float64, param4 bool, param5 string) { fmt.Println("param1:", param1) fmt.Println("param2:", param2) fmt.Println("param3:", param3) fmt.Println("param4:", param4) fmt.Println("param5:", param5) }) // 在Go中监听一个事件, 带返回值 // 使用形参接收参数 // 在JS中入参类型必须相同 // 返回参数可以同时返回多个, 在JS接收时同样使用回调函数方式以多个入参形式接收 ipc.On("go-on-event-demo-argument-return", func(param1 int, param2 string, param3 float64, param4 bool, param5 string) string { fmt.Println("param1:", param1) fmt.Println("param2:", param2) fmt.Println("param3:", param3) fmt.Println("param4:", param4) fmt.Println("param5:", param5) return fmt.Sprintf("%d-%v-%v-%v-%v", param1, param2, param3, param4, param5) }) //内置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) } ``` ```html <!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) }) } // 在Go中监听一个事件, 不带返回值 // 使用形参接收参数 // 在JS中入参类型必须相同 function goOnEventDemoArgument() { ipc.emit('go-on-event-demo-argument', [100, '字符串-Energy', 1000.001, true, "字符串"]); } // 在Go中监听一个事件, 带返回值 // 使用形参接收参数 // 在JS中入参类型必须相同 function goOnEventDemoArgumentReturn() { ipc.emit('go-on-event-demo-argument-return', [100, '字符串-Energy', 1000.001, true, "字符串"], function (result) { writeMessage("result: " + result) }); } </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> <button onclick="goOnEventDemoArgument()">go-on-event-demo-argument</button> <button onclick="goOnEventDemoArgumentReturn()">go-on-event-demo-argument-return</button> <div id="message"></div> </body> </html> ``` 效果图 ​![go-on-event-js-emit-event.gif](https://static.golangjob.cn/230608/e973d89ed73e0609fcbcb324578cad65.gif)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1783 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传