静下心来的个人专栏
上一篇

profobufjs——初步学习

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

首先用一幅图来指出protobuf在显示不同方法之间的关系以及有效消息的概念:在这里暂时不需要理解,后面我们会一点一点解释。重点重點重点

主要注意的是,我们在介绍各个不同的方法的时候,Message指的是一个任意的消息类:

为了说明问题,我的demo代码用浏览器端的代码来演示:

<!doctype html>
<head>
	<style>
	</style>
	<script src="js/protobuf.js"></script>
</head>

<body>
<script>
	var jsonDescriptor = {
	  "nested": {
		"awesomepackage": {
		  "nested": {
			"AwesomeMessage": {
			  "fields": {
				"awesomeField": {
				  "type": "string",
				  "id": 1
				}
			  }
			}
		  }
		}
	  }
	};
	var root = protobuf.Root.fromJSON(jsonDescriptor);
	console.log('root:',root);
	// Obtain a message type
    var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");
	console.log('AwesomeMessage :',AwesomeMessage);
    // Exemplary payload
    var payload = { awesomeField: "AwesomeString" };

    // Verify the payload if necessary (i.e. when possibly incomplete or invalid)
    var errMsg = AwesomeMessage.verify(payload);
    if (errMsg)
        throw Error(errMsg);

    // Create a new message
    var message = AwesomeMessage.create(payload); // or use .fromObject if conversion is necessary
	console.log('message :',message);

    // Encode a message to an Uint8Array (browser) or Buffer (node)
    var buffer = AwesomeMessage.encode(message).finish();
	console.log('buffer :',buffer);
    // ... do something with buffer

    // Decode an Uint8Array (browser) or Buffer (node) to a message
    var message = AwesomeMessage.decode(buffer);
	console.log('decode message :',message);
    // ... do something with message

    // If the application uses length-delimited buffers, there is also encodeDelimited and decodeDelimited.

    // Maybe convert the message back to a plain object
    var object = AwesomeMessage.toObject(message, {
        longs: String,
        enums: String,
        bytes: String,
        // see ConversionOptions
    });
	console.log('origin object :',object);
</script>
</body>
</html>

这段代码的简单输出如下:

我们首先看这一部分,这一部分用JSON对象描述符来初始化root实例:

protobuf.Root.fromJSON(descriptor)

var root = protobuf.Root.fromJSON(jsonDescriptor);
console.log('root:',root);

可以看到我们的消息AwesomeMessage已经实例化好了,而且这个类型包含了一些基本的方法,比如:encode,

decode,fromObject,toObject,verify。这些方法和我们最上面图展示的方法是不是很类似。

Message.verify(payload)

我们先来看Message.verify(payload)

我们的代码首先通过var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");获得自己定义的消息类型。然后创建一个消息,最后调用var errMsg = AwesomeMessage.verify(payload);注意,如果这里的消息有问题,比如多了一个字段,或者字段类型不正确,则会返回具体的错误信息,这样可以验证这个消息是不合法的。

 

Message.create(object)和Message.encode(message)

我们再来看Message.create(object)

我们的代码使用var message = AwesomeMessage.create(payload);创建了一个消息对象实例,然后调用var buffer = AwesomeMessage.encode(message).finish();实现了消息到Uint8Array的转化。如下图所示:

Message.decode(buffer)和Message.toObject(message)

我们通过调用var message = AwesomeMessage.decode(buffer);将buffer转化为了具体的消息实例(AwesomeMessage),以及

var object = AwesomeMessage.toObject(message, {
    longs: String,
    enums: String,
    bytes: String,
    // see ConversionOptions
});

这段代码最后将消息对象转化为具体的Object对象。

以上就是一个protobuf从编码到解码的一个完整的流程,不难看出,这个流程还是比较清晰的,不过这里给大家伙留下了一个疑问?

为什么要采用这种编码和解码的方式呢?或者说它的优势和劣势是什么呢?

 

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们