Flutter嵌入式arm64 linux数据交互方式验证(共享内存、GRPC)
flutter 嵌入式arm64 linux板子数据交互方式,内存共享和grpc
1 数据交互方式选择
1.1通过GRPC服务读写数据
整个业务分为3层,显示层、服务层、数据提供处理层,显示层是前端程序,通过GRPC调用服务层,服务层再调用数据提供和处理层进行数据交互;

1.2 通过共享内存获取数据,通道写数据
整个业务分为2层,前端显示层、数据提供和处理层,前端app通过共享内存读取数据,通过管道向下写数据;

2 两种交互方式优势对比
2.1 三层架构方式
- 能有效分离代码,降低业务层代码之间耦合
- 服务层可实现多通道、多协议之间兼容,方便移植
- 通信速率相对要有一些延迟。
- 定位问题需要三方会诊。
2.2 两层架构方式
- 通信效率高;
- 部署方便;
- 问题定位容易;
- 前端代码冗余度升高,尤其是在实现多通道的业务需求的时候,代码会更加复杂;
3 创建Flutter FFI插件
想要获取共享内存中的数据,需要用C读写共享内存,那么就要涉及到dart和C的交互,需要用到FFI(Foreign Function Interface),FFI还支持和原生平台代码进行映射交互(Object-C,Swift,Java,Kotlin, C, C++)
3.1创建插件
flutter create - -platform=linux - -template=plugin_ffi share_memory
3.2 编写C代码和头文件
如下图编写C代码,和共享内存交互:

3.3 使用ffigen生成映射代码
dart run ffigen --config ffigen.yaml
命令中需要用到ffigen.yaml这个配置文件,配置文件中需要加
type-map:
'native-types':
'char':
'lib': 'pkg_ffi'
'c-type': 'Utf8'
'dart-type': 'Utf8'
用来处理生成的映射对象的字符串,用utf8解码,配置好后生成的代码如下:

生成generated.dart文件后就可以看到,里边的方法、对象等都是和C提供的方法和结构体是一一对应的,有映射关系。
3.4 编写插件暴露接口
生成generated.dart文件后,就可以在share_memory.dart文件中编写调用逻辑了,如果是耗时逻辑,就必须使用Isolate隔离进行调用,因为C的执行会阻塞flutter的主线程的执行。

3.5 项目中插件调用
插件中有example可以直接测试调用插件的方法,和外部项目调用相同
3.5.1 引入插件依赖
在example的pubspec.yaml文件中配置插件(依赖)的引入:

3.5.2 业务调用
调用文件引入插件路径:

方法中调用:

4 调用GRPC服务
4.1 部署GRPC服务
后端开发人员提供arm64架构的release包,拷贝到板子固定目录,当前以/root/pro_ac_app/cSharpServer为例。
4.1.1 csharp GRPC服务配置文件修改
修改appsettings.json, ip改成127.0.0.1:7025, 注意端口号要确保没有被占用;
4.1.2 启动csharp GRPC服务
cd 到/root/pro_ac_app/cSharpServer目录下,执行:./ActionPower.MSA.MCU & 后台启动服务;
4.2 Flutter前端调用GRPC
4.2.1 引入依赖
在pubspec.yaml文件中引入两个依赖:

4.2.2获取.proto文件
后端开发人员提供.proto文件,放置在flutter项目根目录下protos/:

4.2.3生成dart GRPC映射代码
创建grpc_gen.sh文件,如下编辑protoc生成dart代码的指令:

创建完成后,执行次文件,生成dart grpc代码,对应Device.proto:

所以lib/app/common/grpc/下的代码就不要编辑了,因为每次生成后会覆盖;
4.2.4调用
在业务代码中调用csharp GRPC的时候,首先要创建一个Client,如下, DeviceClient对应Device.proto中的service Device,, ClientChannel来自于package:grpc依赖:

然后就可以直接进行调用了,如下调用的是Device.proto中UploadFilePLC这个方法,获取一个文件,读取文件流,分批通过接口上传到固定目录,上传成功后返回文件上传的结果路径和文件总大小;


4.2 待解决问题
目前通过.proto文件生成的dart文件中不包括google.protobuf.Empty,如果包括了Empty这个对象,生成的代码找不到这个对象,因为是谷歌原生库下的empty.proto, 此问题还需要继续查阅解决;
此问题已找到解决方案:
解决方案是在grpc_gen.sh中将引入的google/protobuf/empty.proto文件也配置进去,这样在生成dart代码的时候,同样会将empty.proto生成,完美解决了这个问题;如下图:
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)