Flutter 中 Dio 和 Socket 发送 和 接收 Protobuf 数据
dio和socket
- Dio 使用 proto
- Socket 使用 proto
Dio 使用 proto
- 在pubspec.yaml 安装 dio
dio: ^4.0.6
编译protobuf文件
proto转为dart
发送和接收proto, 可以根据个人的需求,进行封装
- 2022/08/09 修改,在最近的开发的时候,发现的问题,可以有一些公司对headers进行检验了,因此需要将
contentType = "application/x-protobuf"
修改 - 2022/11/08 修改,在修改完,需要重新编辑一次,然后才可以打包项目
- 2022/08/09 修改,在最近的开发的时候,发现的问题,可以有一些公司对headers进行检验了,因此需要将
// 定义一个方法
static ProPost (Function callBack) async {var proto = SearchUserInfoRequest.create(); // SearchUserInfoRequest 为proto中的messagevar userinfo = HttpUserInfo.create();var url = ""; // Ip:Protuserinfo.userGuid = "22222";userinfo.userName = "jack";Uint8List buf = userinfo.writeToBuffer();Options option = Options(headers: {// application/x-protobuf || application/x-www-form-urlencodedHeaders.contentTypeHeader: "application/x-www-form-urlencoded",Headers.accepHeader: "*"},method:"POST",// application/x-protobuf || application/x-www-form-urlencodedcontentType:"application/x-www-form-urlencoded",responseType: ResponseType.bytes,);var dio = Dio();try {final response = await dio.request(url,options:option,data:buf);// 获取到的数据,通过指定的message 解析DevicesAndGroupsMessage tlcs = DevicesAndGroupsMessage.fromBuffer(response.data);} on DioError catch (e) {var ei = e.response?.data;print(ei.runtimeType); // Uin8List// 个人特殊需求TlcsErrorRequest tlcs = TlcsErrorRequest.fromBuffer(ei);return tlcs;}return;callBack(tlcs);
}
- 修改dio插件
进入dio.dart
文件中找到
late Transformer transformer;
然后进入transformer.dart
文件,修改transformRequest
这个方法,
我们会发现在transformRequest中 数据必须是 String
,我们需要数据为Uint8List
,dio
仅仅只是data.toString()
,显然这样是不支持发送Uint8List数据的,因此我们修改一下
修改前:
// 26行
Future<String> transformRequest(RequestOptions options);// 72行@overrideFuture<String> transformRequest(RequestOptions options) async {var data = options.data ?? '';if (data is! String) {if (Transformer.isJsonMimeType(options.contentType)) {return json.encode(options.data);} else if (data is Map) {options.contentType =options.contentType ?? Headers.formUrlEncodedContentType;return Transformer.urlEncodeMap(data);}}return data.toString();}
修改后
// 26行
Future<String> transformRequest(RequestOptions options);// 72行@overrideFuture<String> transformRequest(RequestOptions options) async {var data = options.data ?? '';if (data is! String) {if (Transformer.isJsonMimeType(options.contentType)) {return json.encode(options.data);} else if (data is Map) {options.contentType =options.contentType ?? Headers.formUrlEncodedContentType;return Transformer.urlEncodeMap(data);} else if(data is Uint8List) {/*return data;github上,我见也有人直接 return data;直接返回Uint8List类型我自己试了一下,在未知的位置又报错了,因此可以使用 String.fromCharCodes()*/ return String.fromCharCodes(data);}}return data.toString();}
Socket 使用 proto
- 在pubspec.yaml 安装 web_socket_channel
web_socket_channel: ^1.1.0
编译protobuf文件
proto转为dart
发送和接收proto, 可以根据个人的需求,进行封装
// 简单一个类
class ProtoMsg {static late Socket channel;// 创建连接static createWs(Ip,Prot) async {await Socket.connect(Ip,Prot,timeout: const Duration(seconds:10)).then((value) {channel = value;channel.asBroadcastStream();}).catchError((onError) {// 连接失败,重连createWs(Ip,Prot);});}// 关闭连接static void dispos() {channel.close();}// 发送数据static writeData(buffer) async {/** 头标记 code(4个字节) : 10000* 数据大小 (4个字节) : leng* 保留大小 (4个字节) : 保留* 数据内容 leng个字节*//*// 特殊操作,有关于dart字节的操作var leng = buffer.length; // 获取到proto数据的长度ByteData bdata = ByteData(12 + leng); // 前12个字节预留位置,后面的字节为proto的数据var id = await ByteData.view(bdate.buffer, 0 , 4); //0位开始,4个字节,用于填写code值id.setUint32(0,10000); // 设置 code值var length = await ByteData.view(bdata.buffer,4,4); // 4位开始,4个字节,设置proto数据的长度length.setUint32(0,leng); // 设置 proto的长度var body = await ByteData.view(bdata.buffer,12,buffer.length); // 12位开始,proto数据字节长度,设置proto的数据for(var i = 0;i<leng;i++) {body.setUint8(i,buffer[i]); // 设置proto数据}var buf = Uint8List.view(body.buffer);channel.add(buf);*/channel.add(buffer);}static onReceiver(event) {print(event);ProtoMsg.parseData(event);}static parseData(Uint8List event) async {/** 头标记 code(4个字节) : 10000* 数据大小 (4个字节) : leng* 保留大小 (4个字节) : 保留* 数据内容 leng个字节*//*// 特殊操作,有关于dart字节的操作Uint8List id = event.sublist(0,4); // 截取前4个字节var data = event.sublist(12);var number = await ByteData.view(id.buffer).getInt32(0); // 获取到code值if(number == 500) {TlcsErrorRequest tlcs = TlcsErrorRequest.fromBuffer(data); // 反序列化数据}*/TlcsErrorRequest tlcs = TlcsErrorRequest.fromBuffer(event);}}// 使用方式ProtoMsg.createWs("","");var userinfo = HttpUserInfo.create();userinfo.userGuid = "22222";userinfo.userName = "jack";Uint8List buf = userinfo.writeToBuffer();// 序列号数据ProtoMsg.channel.listen(onReceiver); // 接收到数据ProtoMsg.writeData(buf); // 发送数据
Flutter 中 Dio 和 Socket 发送 和 接收 Protobuf 数据相关推荐
- javasocket连续给服务器发送消息,Java通过Socket发送和接收多条消息
我们需要实现一个Socket客户端,它应该连接到一个接受TCP连接的服务器.如果我通过netcap与服务器进行通信,我会立即得到它的响应(通过命令行).Java通过Socket发送和接收多条消息 的工 ...
- 如何在Linux命令行下发送和接收UDP数据包
众所周知,在传输层有两个常用的协议 TCP 和 UDP,本文介绍在 Linux 命令行下,如何使用 nc 命令发送或接收 UDP 数据包,这些命令的用法对调试 UDP 通信程序将有所帮助. 1. 问题 ...
- QuteCom手记:phapi发送和接收音频数据的流程(ortp portaudio)
phapi发送和接收音频数据的流程简介. 通过ortp库(完整的源代码在ortp工程中)实现. oRTP协议将在另外一篇中介绍,这里只要知道它是用来发送和接收媒体流(音频和视频)的协议. 本篇只记录使 ...
- 计算机网络课程设计——发送和接收TCP数据包以及发送和捕获ARP数据包
1.课程设计要求: 发送和接收TCP数据包:TCP是一种面向连接的.可靠的传输层协议.TCP协议工作在网络层IP协议的基础上.本课程设计的目的是设计一个发送和接收TCP数据包的程序,其功能是填充一个T ...
- Python 通过socket发送list和字典数据
发送端 import socket import json ip = '10.211.55.20' port = 8893 sock = socket.socket(socket.AF_INET,so ...
- UnityWebRequest.Post 发送和接收Json数据
1.C#:发送和接收Json数据 using UnityEngine; using UnityEngine.Networking; using System.Collections; using Un ...
- android 分包粘包_Android Socket 发送与接收数据问题处理: 发送后的数据接收到总是粘包...
先说明一下粘包的概念: 发送时是两个单独的包.两次发送,但接收时两个包连在一起被一次接收到. 在以前 WinCE 下 Socket 编程,确实也要处理粘包的问题,没想到在 Android 下也遇到了. ...
- Java中udp/tcp的发送和接收
一.UDP协议发送数据 发送处理过程: 创建发送端Socket对象--DatagramSocket 创建数据并将数据打包到DatagramPacket对象 通过Socket发送 释放相关资源 发送处理 ...
- 探索 OpenStack 之(15):oslo.messaging 和 Cinder 中 MessageQueue 消息的发送和接收
前言:上一篇文章 只是 RabbitMQ 的科普,本文将仔细分析 Cinder 中 RabbitMQ 的各组件的使用.消息的发送和接收等.由于各流程步骤很多,本文只会使用若干流程图来加以阐述,尽量做到 ...
最新文章
- Redis数据库设置密码
- python excle写数据
- git stash 个人理解
- 阿里基础设施技术亮相SIGCOMM 2018
- python自带gui_Python GUI开发工具中五种类型的相关介绍
- mysql命令_MySQL常用操作命令
- 树莓派3vnc分辨率设置
- %3c?php else:?%3e,[红日安全]代码审计Day15 - $_SERVER['PHP_SELF']导致的防御失效问题
- ie6下的iframe,问题多多。
- keil4 c51安装教程
- 绘制地图其实并不难!如何绘制地图?看看Smartbi的制作方法
- 推荐两款很好用的听书APP
- 电脑连接不上手机和路由器热点解决办法
- 2022第8届中国大学生程序设计竞赛CCPC威海站, 签到题7题
- python小明爱跑步
- AS3 抽象类与接口
- 我今年,二十四五岁 (2018年深有体会)
- ifix从sqlserver里读数据_基于GE Fanuc产品PBS汽车总装生产线监控系统设计
- ZHA_123的自我介绍
- 航空遥感数据集、无人机航拍数据集
热门文章
- 一份标准的渗透测试报告是什么样的?(附报告模板)
- Notability的一些使用技巧及知乎问题总结
- 回文数函数(c语言)
- Delphi 中 InputQuery 实现密码输入
- centos安装realvnc
- 【shopify 1】调研出海项目,发现shopify没有java的相关SDK接口,但是找到一个最新2022年6月的Java项目分享了相关代码,使用docker进行环境搭建、编译,并成功启动
- 基于k3s部署KubeSphere
- Tu te prends pour qui?
- 《三》微软Dynamics CRM 2016单服务器安装部署(Dynamics CRM 2016 安装)
- 程序员如何打造自己的个人IP?