这里写自定义目录标题
ProtoBuf介绍/安装
1.protobuf是一种语言无关,平台无关,可扩展的序列化结构数据,它一般用于通信协议,数据存储,但是也有用来进行请求数据等等。因为现在多数的项目,讲究的是前后端分离,而且多数前端的项目为:原生js配合jquery,vue,reac,php。
2.protobuf是一种灵活,高效,自动化的结果数据序列化方式,类比xml,但是比xml更小3-10倍,更快20-100倍,更为简单
3.文件的后缀为.proto文件,定义数据结构
ProtoBuf使用
message关键字定义消息名
Message User {
字段规则:required -> 字段只能也必须出现1次(一般代表token)
字段规则:optional -> 字段可出现0次或1次(一般用于多条件查询)
字段规则:repeated -> 字段可出现任意多次()
类型:int32(比较常用),int64,sint32,sint64,string(比较常用),32-bit
字段编号: 0
创建一个proto文件
syntax = "proto3";
package User;
message UserLogInRequest{
string userName = 1;
string userPwd = 2;//Use Md5 Encryption
//用户登录类型
enum OrderPlatformType{
PlatformUnknown = 0;
WebBrowser = 1; //Web Browser
Android = 2; //Android
IOS = 3;
}
OrderPlatformType platformType = 3; //Platform Type
}
message UserLogInResponse{
string sessionId = 1; //Session
string userPrivilege = 2;
uint64 servTimestamp = 3; //timestamp:1577444840
string formatTimestamp = 4;
}
message OrderUserInfo_s{
string UserName = 1;
string UserGuid = 2;
}
message SearchOrder_s{
OrderUserInfo_s UserInfo = 1;
//订单查询类型
enum OrderSearchType{
SearchType_UserID = 0;//客户
SearchType_OrderID = 1;//订单号
SearchType_PartID = 2;//料号
SearchType_NotFinished = 3;//未完成订单
SearchType_Time = 4;//时间
}
repeated OrderSearchType OrderType = 2;
string starttime = 3;//开始时间
string endtime = 4;//结束时间
string userid = 5; //客户端ID
string model = 6;//型号
string orderid = 7; //订单号
string partid = 8;//料号
uint32 page = 9;//第几页
uint32 rowcount = 10;// 1页多少数据
}
message ResultOrder_s{
message OrderInfo_s{
string orderid = 1;
string partid = 2;
string userid = 3;
string model = 4;
string macsource = 5;
string describe = 6; //浜у搧鎻忚堪
repeated uint32 license = 7;
repeated string language = 8;
uint32 num = 9;
string starttime = 10;
string expectouttime = 11;
uint32 woutnum = 12;
message LockServer_s{
uint32 index = 1;
string srvzip = 2;
string srvzport = 3;
bool bsrvzs = 4;
bool bsrvfs = 5;
uint32 niZP = 6;
bool bEnable = 7;
}
repeated LockServer_s LockServer = 13;
message HideServer_s{
string srvip = 1;
string srvlimittime = 3;
bool bsrvzs = 4;
bool bvideo = 5;
bool bgps = 6;
bool bEnable = 7;
}
HideServer_s HideServer = 14;
uint32 ADASPro = 15;
repeated uint32 ADASlicense = 16;
uint32 state = 17;
string author = 18;
string completetime = 19;
uint32 serverlicense = 20;
string remarks = 21;
string customtype = 22;
string printlanguage = 23;
string ContractNo = 24;
}
repeated OrderInfo_s OrderInfo = 1;
uint32 totalcount = 2;
string strDownFilePath = 3;
repeated uint32 Mailman = 4;
}
message GetOrderAttribute_s{ //发送命令GetProductionNoticeAttribute
OrderUserInfo_s UserInfo = 1;
}
//语言对应表
enum LanguageList{
Language0 = 0;//简中
Language1 = 1;//英语
Language2 = 2;//繁中
Language3 = 3;//韩语
Language4 = 4;//日语
Language5 = 5;//德语
Language6 = 6;//俄语
Language7 = 7;//法语
Language8 = 8;//葡萄牙语
Language9 = 9;//土耳其语
Language10 = 10;//西班牙语
Language11 = 11;//意大利语
Language12 = 12;//波兰
Language13 = 13;//波斯
Language14 = 14;//泰语
Language15 = 15;//希伯来语
Language16 = 16;//阿拉伯语
Language17 = 17;//印尼语
Language18 = 18;//保加利亚语
Language19 = 19;//罗马尼亚语
Language20 = 20;//希腊语
Language21 = 21;//斯洛伐克语
Language22 = 22;//立陶宛语
Language23 = 23;//越南语
Language24 = 24;//捷克语
Language25 = 25;//匈牙利语
}
//用户登录类型
enum OrderPlatformType{
PlatformUnknown = 0;
WebBrowser = 1; //Web Browser
Android = 2; //Android
IOS = 3;
}
//AI厂商对应表
enum AIManufacturerList{
AIManufacturer0 = 0;//通立
AIManufacturer1 = 1;//魔视
AIManufacturer2 = 2;//天瞳
}
message ResultOrderAttribute_s{
repeated string AllMode =1; //所有型号
repeated LanguageList AllLanguage =2; //所有语言
repeated AIManufacturerList AllAIManufacturer =3; //所有AI厂商(具体定义见宏和枚举页面)
repeated string ServerAddress = 4;//隐藏服务器地址
uint32 UserID = 5;//添加客户端ID
}
message DelProductionNotice_s{
OrderUserInfo_s UserInfo = 1;
string orderid = 2; //订单号
}
message OrderErrorRequest{
uint32 errType = 1;
uint32 requestCmdId = 2; //
string errTime = 3;
string appType = 4;
string errDes = 5;
}
message ExportProductionNotice_s{
string dirpath = 1;// 文件目录
string fileName = 2;//文件名
}
js中使用
在项目根目录使用 (* npm || cnpm *) 安装 google-protobuf
一旦定义了message,就可以在.proto文件上运行protoc.exe,编译成指定的语言数据类
// 将proto文件生成js文件
protoc.exe --js_out=import_style=commonjs,binary:. myproto.proto;
//如果项目是vue,react,uniapp等等,通过node中的require,引入到文件中进行操作
const myProto = require('@/proto/myproto_pb.js');
如果项目想使用原生开发,甚至WebPack都不使用,就需要使用安装browserify将生成的proto_person_pb.js文件编译.
1.创建一个export.js文件,内容如下:
var myProto = require('./myproto_pb.js');
module.exports = {
DataProto: myProto,
}
2.在当前文件下运行命令行,将文件编译,内容如下:
browserify export.js > bundle.js
3.在html文件中直接引用bundle.js及可使用
ProtoBuf如何工作
在.proto文件中定义message类型,每一个message是一个消息的小逻辑记录,包含一系列的name-value对,每一个message类型都有一个或多个具有唯一编号的字段,每一个字段都有一个名称和一个值类型,其中值的类型包括数字(整数或浮点数),布尔值,字符串,原始字节,这意味着允许分层构建数据,也可以指定optional字段,required字段和repeated字段
在我们访问和设置字段时,在js中是无法直接设置/访问字段的,在.js文件中提供了(例如:name,setName(),getName())指定的方法进行操作,在内部提供了==serializeBinary()方法,将数据序列化,以及deserializeBinary()反序列化,但是我们在反序列化的数据是以数组的形式呈现出来的,因此可以通过使用内部的toObject(true,需要对象化的数据)==方法将数据对象化,这样我们就可以进行数据的操作
封装请求 request.js
const myProto = require('@/proto/myproto_pb.js');
const md5 = require('./md5.js');
const serverUrl = '****';
class Person{
constructor() {}
_request(url, method, params,Response) {
var bytes = params.serializeBinary();
var promise = new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('post',serverUrl + url,true);
// 设置POST请求的请求头
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.responseType = "blob"; // 返回类型blob
xhr.onload = function (oEvent) {
var blob = this.response;
var reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = function (e) {
var buf = new Uint8Array(reader.result);
var obj2 = new proto.User[Response].deserializeBinary(buf);
var data = new proto.User[Response].toObject(true,obj2);
if(obj2) {
resolve(data);
}else {
reject("网络出错");
}
}
}
xhr.send(bytes);
xhr.onreadystatechange = function() {
// console.log(xhr.status)
// 判断readyState就绪状态是否为4,判断status响应状态码是否为200
// if (xhr.readyState == 4 && xhr.status == 200) {
// //获取服务器的响应结果
// var responseText = xhr.responseText;
// option.success(JSON.parse(responseText))
// console.log(buf)
// }else {
// option.error(xhr.statusText)
// }
}
});
return promise;
}
}
class Api extends Person {
constructor() {
super();
}
// 用户进行登录
UserLogInResponse(url,method,params) {
let UserLogInRequest = new myProto.UserLogInRequest();
UserLogInRequest.setUsername(params['Username']);
UserLogInRequest.setUserpwd(md5(params['Userpwd']));
UserLogInRequest.setPlatformtype(params['Platformtype']);
return this._request(url, method, UserLogInRequest,'UserLogInResponse');
}
// 获取订单信息
serachProduct(url,method,params) {
var searchOrder = new proto.User.SearchOrder_s();
var OrderUserInfo = new proto.User.OrderUserInfo_s();
OrderUserInfo.setUsername(params['UserName']);
OrderUserInfo.setUserguid(params['sessionId']);
searchOrder.setPage(params['Page']);
searchOrder.setRowcount(params['Rowcount']);
searchOrder.setUserinfo(OrderUserInfo);
return this._request(url, method, searchOrder,'ResultOrder_s');
}
//获取订单属性
GetOrderAttribute_s(url,method,params) {
var OrderUserInfo = new proto.User.OrderUserInfo_s();
var GetOrderAttribute = new proto.User.GetOrderAttribute_s();
OrderUserInfo.setUsername(params['UserName']);
OrderUserInfo.setUserguid(params['sessionId']);
GetOrderAttribute.setUserinfo(OrderUserInfo);
return this._request(url, method, GetOrderAttribute,'ResultOrderAttribute_s');
}
// 删除生产通知单
DelProductionNotice_s(url,method,params) {
var OrderUserInfo = new proto.User.OrderUserInfo_s();
var DelProductionNotice = new proto.User.DelProductionNotice_s();
OrderUserInfo.setUsername(params['UserName']);
OrderUserInfo.setUserguid(params['sessionId']);
DelProductionNotice.setUserinfo(OrderUserInfo);
DelProductionNotice.setOrderid(params['Orderid']);
return this._request(url, method, DelProductionNotice,'OrderErrorRequest');
}
// 导出生产通知单
ExportProductionNotice(url,method,params) {
var searchOrder = new proto.User.SearchOrder_s();
var OrderUserInfo = new proto.User.OrderUserInfo_s();
OrderUserInfo.setUsername(params['UserName']);
OrderUserInfo.setUserguid(params['sessionId']);
searchOrder.setPage(params['Page']);
searchOrder.setRowcount(params['Rowcount']);
searchOrder.setUserinfo(OrderUserInfo);
return this._request(url, method, searchOrder,'ExportProductionNotice_s');
}
}
let Message = new Api();
module.exports = {
Message
}
在home.js文件中使用
import {
Message
} from '../api/request.js';
// 获取订单信息
async Text2({
commit
},data) {
let res = await Message.serachProduct('SearchProductionNotice','POST',data);
// console.log(res)
},
// 获取订单信息
async Text3({
commit
},data) {
let res = await Message.GetOrderAttribute_s('GetProductionNoticeAttribute','POST',data);
// console.log(res)
},
// 导出生产通知单
async Text5({
commit
},data) {
let res = await Message.ExportProductionNotice('ExportProductionNotice','POST',data);
// console.log(res);
},