这段时间开始将研发重心从OpenGL转向数据的序列化,再转向数据的传输了。在查看了一些前辈以及高手们有关登录模块的实现后,我也制定了一个自己的登录模块的解决方案。这其中我考虑到要使用json作为数据传输的格式,后面发现json二进制可以让数据更小,于是研究重心转向了json二进制,慢慢地转向了MsgPack这个开源的库,最后一个下午加上晚上,终于实现了用Qt打包MsgPack的数据再由node.js解包的操作。
蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/48342433。欢迎同行前来探讨。
在决定使用json二进制方案的时候,我发现其实Qt的QJsonDocument类有提供这样的方法,叫做QJsonDocument::toBinaryData( )。我尝试了一下,在转出时候,我将其输出到console中,发现这样导出的格式是Qt特有的json二进制的表达方式,而如果涉及到客户端和服务端交互的话,一定要有其它系统认识Qt这样的二进制表达方式才行。目前还没有发现node.js或是Qt以外的库支持Qt这种json的二进制表达方式,于是这种方法放弃了。
在搜寻解决方案的时候,我发现了一个库,叫做MsgPack(官网:http://msgpack.org/),这个库声称可以保存比json更小的数据。其实开始阶段我对这个并不关心,我关心的是希望能够提供多语言多环境的绑定,这样可以实现我的目标。幸好它提供了很多语言的绑定,其中包括了node和Qt:
于是我立即下载了这两个版本的MsgPack。原来这些语言的绑定是不同的作者完成的。每一个作者都会将自己的绑定放在github上,供人测试和参考。
其中node.js的版本通过
npminstall msgpack5 –save
指令进行安装;
Qt的版本通过
gitclone https://github.com/romixlab/qmsgpack.git
方法进行下载
其中我对Qt这块儿更加熟悉一些,我不急着按照它的指示去编译安装,我使用git clone了一遍以后,查看了一下它的pro文件,懂得了它的构建方法。我尝试了一段时间,并且编写了一个演示程序,发现在Windows Phone的构建套件上无法编译通过(事实上我估计在所有MSVC编译器上也无法通过),于是我不得不修改一下源代码,以便这个库能够编译通过。我将修改后的代码上传到我的github上。如果大家要使用MsgPack做Windows、WindowsRT和Windows Phone应用,总之是依赖MSVC编译器的应用的话,那么请下载我的版本吧:
gitclone https://github.com/jiangcaiyang/qmsgpack-patched.git
这里我想到的是将这个库的源码和我的项目一起编译,于是我没有使用它的cmake和pro文件,而是自己写了一个类似的pri文件,内容是这样的:
# QMsgPack.pri #QMSGPACK_PATH = /media/jiangcaiyang/我的软件盘/Develop/qmsgpack QMSGPACK_PATH = E:/Develop/qmsgpack !exists( $$QMSGPACK_PATH ) { error( "QMsgPack.pri: The specified path does not exist." ) } DEFINES += MSGPACK_MAKE_LIB INCLUDEPATH += $$QMSGPACK_PATH/src SOURCES += $$QMSGPACK_PATH/src/msgpack.cpp \ $$QMSGPACK_PATH/src/msgpackcommon.cpp \ $$QMSGPACK_PATH/src/private/pack_p.cpp \ $$QMSGPACK_PATH/src/private/unpack_p.cpp \ $$QMSGPACK_PATH/src/private/qt_types_p.cpp \ $$QMSGPACK_PATH/src/msgpackstream.cpp HEADERS += $$QMSGPACK_PATH/src/msgpack.h \ $$QMSGPACK_PATH/src/private/pack_p.h \ $$QMSGPACK_PATH/src/private/unpack_p.h \ $$QMSGPACK_PATH/src/private/qt_types_p.h \ $$QMSGPACK_PATH/src/endianhelper.h \ $$QMSGPACK_PATH/src/msgpackcommon.h \ $$QMSGPACK_PATH/src/msgpack_export.h \ $$QMSGPACK_PATH/src/msgpackstream.h
好了,为了测试并且使用MsgPack,我参照原作者的例子,写了一个例子程序,我将例子程序上传至github中,大家可以下载测试一下:
gitclone https://github.com/jiangcaiyang/qt-msgpack-test.git
演示程序是这样的:
Android上是这样的:
我们可以通过这个演示程序计算出,一个字符串“Hello”经过QMsgPack打包再进行base64编码后,变成字符串“pUhlbGxv”。虽然实际上是增加了字符串的量。同理,一个json对象:
vartestJson=
{
"key":"Great",
"value":12,
"group":[12,35,63,13]
};
经过QMsgPack打包后在base64编码后,变成的是这个:
g6Vncm91cJTLQCgAAAAAAADLQEGAAAAAAADLQE+AAAAAAADLQCoAAAAAAACja2V5pUdyZWF0pXZhbHVly0AoAAAAAAAA
接下来介绍一下如何在node.js中将这样的数据还原。
首先使用npm命令在你的项目中安装msgpack,命令是:
npminstall msgpack5 –save
接着在你认为可能运行的Javascript代码中测试一下效果。我这边写了一个这样的例子:
var msgpack = require( "msgpack5" )( ); module.exports = function ( app ) { app.get( "/test_parse_msgpack", function ( req, res ) { // 将要在这里进行解析msg_pack console.log("test_parse_msgpack function is called."); var qtbase64Text = "g6Vncm91cJTLQCgAAAAAAADLQEGAAAAAAADLQE+AAAAAAADLQCoAAAAAAACja2V5pUdyZWF0pXZhbHVly0AoAAAAAAAA"; var qtpackedBuffer = new Buffer( qtbase64Text, "base64" ); var decoded = msgpack.decode( qtpackedBuffer ); console.log( "un base64 string: " + qtpackedBuffer.toString( ) ); console.log( "decoded: " + JSON.stringify( decoded ) ); // 最后得到的是:{"group":[12,35,63,13],"key":"Great","value":12} qtpackedBuffer = undefined; } ); }
使用起来就是那么简单,我们看到,将原有Json打包的数据从“g6Vncm91cJTLQCgAAAAAAADLQEGAAAAAAADLQE+AAAAAAADLQCoAAAAAAACja2V5pUdyZWF0pXZhbHVly0AoAAAAAAAA”还原成{"group":[12,35,63,13],"key":"Great","value":12}。可谓十分方便。
有了这样的基础,接下来在做登录模块以及后续的业务逻辑可就方便了。