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

介绍

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>

效果图

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yanghye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值