小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言: 今天刚看到,可以【搬运自己的原创文章】参加“程序员必备小知识”活动,十分激动。 想起来之前在某平台上还有几篇技术文章,觉着掘金技术氛围更浓厚,正想搬过来。
原文链接: go-flutter开发桌面应用(五) go-flutter的Go端向Dart端发送消息 - 知乎 (zhihu.com)
正文
对于go-flutter插件,有很多情况需要从Go端向Dart端发送消息,比如一些定时处理、异步处理。
如果只是Dart端的动作去调用go-flutter的插件里的函数,那就和传统的网页请求一样了,网页端发送请求,服务端返回响应在网页显示。
如果能在go-flutter的Go端的代码能向Dart端发送消息,就有些像是WebSocket了,实现双向发送消息。
go-flutter的Go端向Dart端发送消息,这个一开始实在是不知道怎么去调用。也和一个知乎好友的想法一样,曾经想着要不要用TCP去实现。但是个人对TCP又一点儿也不懂,遂放弃。
就在前几天,忽然想到这样的需求是很广泛的,go-flutter就该实现了才对,所以又在go-flutter的github仓库上一通找,然后在go-flutter的插件的wiki中找到了具体的用法。
也是通过消息通道来实现,Go端向消息通道发送消息,Dart端监听消息并处理。
Go端代码(上面链接里的内容CV到此):
// Golang
channel := plugin.NewMethodChannel(messenger, "samples/demo", plugin.StandardMethodCodec{})
err := p.channel.InvokeMethod("test", nil)
// error handling..
Dart端代码(上面链接里的内容CV到此):
// Dart
const platform_channel = MethodChannel("samples/demo");
platform_channel.setMethodCallHandler((MethodCall methodCall) async {
print(methodCall.method); // prints: test
});
官网文档(Github上go-flutter的插件的wiki)上还提供了一个Go端向Dart端发送完消息,等待Dart端响应结果的用法。
Go端代码(上面链接里的内容CV到此):
// Golang
channel := plugin.NewMethodChannel(messenger, "samples/demo", plugin.StandardMethodCodec{})
reply, err := channel.InvokeMethodWithReply("test", nil) // blocks the goroutine until reply is avaiable
// error handling..
spew.Dump(reply) // prints 5 seconds later: (string) (len=21) "reply from dart: test"
Dart端代码(上面链接里的内容CV到此):
// Dart
const platform_channel = MethodChannel("samples/demo");
platform_channel.setMethodCallHandler((MethodCall methodCall) async {
print(methodCall.method); // prints: test
await Future.delayed(Duration(seconds: 5));
return "reply from dart: " + methodCall.method;
});
Go端发送完消息后等待Dart端响应结果的用法鄙人没有尝试,应该不难。
鄙人只试了下Go端向Dart端发送消息的用法,已添加到第一节的工程中。
GitHub - bettersun/hellogoflutter
具体机能是添加了一个从Go端向Dart端定时发送消息的处理。
主要代码:
Go端:
定义机能函数:
// 向Dart端发送消息(定时)
func sendInterval(channel *plugin.MethodChannel) {
ticker := time.NewTicker(time.Second * 1)
go func() {
for _ = range ticker.C {
fmt.Println("sendInterval")
err := channel.InvokeMethod("interval", time.Now().Format("2006/01/02 15:04:05"))
if err != nil {
log.Println(err)
}
}
}()
}
初始化插件时在新的goroutine里运行上面定义的机能函数。
// 初始化插件
func (HelloPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
channel := plugin.NewMethodChannel(messenger, channelName, plugin.StandardMethodCodec{})
channel.HandleFunc(hello, helloFunc)
channel.HandleFunc(message, messageFunc)
// 向Dart端发送消息
go sendInterval(channel)
return nil
}
Dart端:
在initState()添加对消息通道的监听。
参数的method是Go端发送过来的函数名。
参数的arguments是Go端发送过来的函数的返回值,类型是dynamic,需要根据具体类型进行解析。
class _HelloPageState extends State<HelloPage> {
String timeNow = '';
@override
void initState() {
// 监听Go端发过来的消息
HelloPlugin.channel.setMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'interval') {
setState(() {
print(methodCall.arguments);
timeNow = methodCall.arguments;
});
}
});
super.initState();
}
// ...
}
运行结果如下,标题栏显示的时间是Go端发送过来的时间。