Heim  >  Artikel  >  Web-Frontend  >  So lassen Sie JS automatisch mit Proto-Js übereinstimmen

So lassen Sie JS automatisch mit Proto-Js übereinstimmen

php中世界最好的语言
php中世界最好的语言Original
2018-03-16 10:49:121795Durchsuche

这次给大家带来让JS自动匹配出proto Js的方法,JS自动匹配出proto Js的方法的注意事项有哪些,下面就是实战案例,一起来看一下。

在与后端的WebSocket通信时,前端要带一个proto文件是一个累赘的事情。首先是明显的曝光了协议实体对象,再一个浏览器客户端很容易会缓存该文件,新的协议更新可能导致客户端不能使用,另外在cdn服务器上还需要配置.proto类型客户端才能下载过去。真是遗毒不浅,自己使用的时候会注意这些,但给别人使用的时候就很不乐观了,所以这次全部将proto文件转成JavaScript对象,省去协议文件和加载的步骤。

先看代码:

  args = [].slice.call(arguments, 1 obj =  ( i = 0; i < args.length; i++ p = key = i + 1 protobuf.Field(p[0], key, p[1] || "string" obj =  ( i = 0; i < list.length; i++ ( protobuf == "undefined") ;=  protobuf.Root().define("IMEntity""Token", ["UserID"], ["Token"], ["Device"], ["Version", "int32"], ["Appkey""Feedback", ["ResultCode", "int32"], ["ResultData"], ["Seq", "int32"], ["MsgID""ReceiptType", ["Receive", "Read"
    };

proto 主要有两种类型,Type和Enum。Type对应协议中的message,相当于是类。Enum就是枚举类型

var Root  = protobuf.Root,
    Type  = protobuf.Type,
    Field = protobuf.Field;var AwesomeMessage = new Type("AwesomeMessage").add(new Field("awesomeField", 1, "string"));var root = new Root().define("awesomepackage").add(AwesomeMessage);

枚举的创建不要需要Field。只需要add 字段名即可。那么接下来的问题是,手写root.add 也很烦,因为要一个一个对照属性,不断的复制粘贴,很容易出错。所以又做了个自动生成代码的页面:

 <textarea id="content">        //登陆Token        message Token{
        string UserID = 1;    //登陆接口返回的IMUserID
        string Token = 2;    //登陆接口返回的Token
        string Device = 3;    //客户端设备号
        int32  Version = 4;    //版本号,发布前与服务端约定值
        string Appkey = 5;    //客户端Appkey        }       
        //收到私信        message ReceivePrivateMessage{
        string MsgID = 1;        //消息id
        string SenderID = 2;    //发送者id
        string ReceiverID = 3;    //接收者id
        string Content  = 4;    //消息内容。客户端转换成业务相关的实体后,再做后续处理(客户端使用,服务器不做任何处理,原样下发)
        bool Ack = 5;              //是否需要已读回执
        int32 SendDateTime = 6;    //消息发送时间
        int32 ContentType = 7;    //内容类型(客户端使用,服务器不做任何处理,原样下发)        }        //回执类型        enum ReceiptType{
        Receive = 0;                      //已收回执(收到消息后立即发送给服务器的回执)
        Read = 1;                        //已读回执(用户进入消息阅读界面后发送给服务器的回执)        }    </textarea>
    <p id="result"></p>
    <script>        function start() {
            $("#result").html("");
            $("#result").append('root = new protobuf.Root().define("IMProtoEntity")<br>');            var reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)/g,// 过滤注释
          str = $('#content').val(); // 欲处理的文本
            // console.log(str.match(reg));// 打印出:匹配子串
            var news = str.replace(reg, "");            // console.log(news); // 打印出:原文本
            var reg1 = /[message|enum].*?{/mg;            var regobj = /{[^}{]*?}/g;//新地址
            var names = news.match(reg1);            var protos = news.match(regobj);            // console.log(names, protos);
            var root = {};            for (var i = 0; i < names.length; i++) {                var rawname = names[i];                var rawObj = protos[i];                //if (~rawname.indexOf("message"))
                if (!rawObj) continue;                var name = rawname.replace("{", '').replace("message ", '').replace("enum ", '');                var obj = { name: name };                if (~rawname.indexOf("enum")) {
                    obj["type"] = "enum";
                }
                rawObj = rawObj.replace("{", '').replace("}", '');                var protolist = rawObj.split(';');                //  console.log("protolist", protolist);
                var plist = [];                for (var j = 0; j < protolist.length; j++) {                    var p = $.trim(protolist[j]);                    if (p) {                        var args = [];                        var list = p.split(' ');                        //  console.log("list", list);
                        list.forEach(function (n) {
                            n && args.push(n);
                        }),                        //  console.log("args", args);                        plist.push(args);
                    }
                }
                obj.list = plist;
                console.log(obj);
                toProto(obj);
            }
        }
        start();        function toProto(obj) {            var root = "root";            var fun = "createProto";            var enumfun = "createEnum";            var str = root + '.add(';            var args;            if (!obj.type) {//message
                args = '';                for (var i = 0; i < obj.list.length; i++) {                    var item = obj.list[i];                    //老协议2.0
                    if (item[0] == "required" || item[0] == "optional") {
                        item.shift();
                    }                    //新协议3.0
                    if (item[0] != "string") {
                        args += '["' + item[1] + '","' + item[0] + '"]';
                    } else {
                        args += '["' + item[1] + '"]';
                    }                    if (i < obj.list.length - 1) args += ",";
                }
            } else {//enum
                args = '[';                for (var i = 0; i < obj.list.length; i++) {                    var item = obj.list[i];
                    args += '"' + item[0] + '"';                    if (i < obj.list.length - 1) args += ",";
                }
                args += ']';
            }            var all = str + (obj.type ? enumfun : fun) + '("' + obj.name + '",' + args + '));';            //  console.log(all);
            $("#result").append(all + "<br>");
        }    </script>

然后页面上会得到:

红色部分复制到工程里面就可以用了。当然要带上createProto和createEnum两个方法。proto的格式要规范,毕竟start里面是以空格split的。相对于protobuf.load("xx.proto",callback)的方式要好很多。load对位置要求比较死板,一定要在根目录。而且有类型不存在就会报错,终止程序。add方法不存在找不到类型的错误。另外速度也快了很多。 

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎样让js暂停执行

jquery做出评分系统

Das obige ist der detaillierte Inhalt vonSo lassen Sie JS automatisch mit Proto-Js übereinstimmen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn