使用MsgPack配合Qt應用程序和node.js應用程序的數據傳輸

使用MsgPack配合Qt應用程序和node.js應用程序的數據傳輸

       這段時間開始將研發重心從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}。可謂十分方便。

有了這樣的基礎,接下來在做登錄模塊以及後續的業務邏輯可就方便了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章