ことばアルバム

にわかエンジニアのにわか備忘録

cocos2d-xでhttp通信 その2

前回のエントリーの続きです。
前回は「Http通信してレスポンスのデータをログに出そう!」という、とても実用性が乏しい内容でしたが、今日は結構使える奴です。
今回は「リクエストパラメータを付けてHttp通信してJson形式のレスポンスをパースしてデータを取り出す」というものです。
つまり前回のエントリーのリベンジです。
Web系の人には結構おなじみのやつかもしれません。


実装

今回使うプロジェクトは前回のエントリーで用意したものです。
Webアプリケーション側も引き続き流用します。

 
まず、Webアプリケーション側のroutes/index.jsを下記のように書き換えます。

/*
 * GET home page.
 */

exports.index = function(req, res){
  //res.render('index', { title: 'Express' });

  var data = {};
  data.id = req.body.id;
  data.name = 'sample-chan';
  
  res.send(JSON.stringify(data));
};

ここでは、リクエストを受けた時に、リクエストのbodyにくっついてるパラメータをレスポンスのデータに使用し、Json形式でレスポンスデータを返すという事を行っています。
あくまでサンプルなのでこんだけシンプルな感じですが、本当はリクエストパラメータを使って認証したり何かしらを付与したりアイテムを使ったり、、など色々行う事になりそうです。
次にapp.jsの31行目を書き換えます。

app.post('/', routes.index);

分かりづらいですが、get()からpost()に変えました。
あとは、前回同様node app.jsで起動したら、こちらは完了です。

 
続いてcocos2d-x側です。
まずはJsonをパースする用のライブラリを使うために、HelloWorldScene.cppの上部に下記を付け足します。

#include "spine/Json.h"
#include "cocos-ext.h"

using namespace cocos2d::extension;

次に、リクエストを送る方を書き換えます。

void HelloWorld::httpRequest()
{
    auto httpRequest = new HttpRequest();
    
    httpRequest->setUrl("http://localhost:3000");
    httpRequest->setRequestType(HttpRequest::Type::POST); // GETからPOSTに変更
    httpRequest->setResponseCallback(this, httpresponse_selector(HelloWorld::callback));
    
    // 追加分
    const char* postData = "id=10";
    httpRequest->setRequestData(postData, strlen(postData));
    
    network::HttpClient::getInstance()->send(httpRequest);
}

//追加分のところの2行を新しく付け加えました。
今回はidというキーに対して10という値のデータをリクエストパラメータとして用意しました。
そして、さりげなくHttpRequestのTypeをGETからPOSTに変更しています。
ほんの数十分しか触ってないのではっきりとは分かっていませんが、どうやらsetRequestData()した内容はPOSTで送らないと、受け側のreq.bodyが空っぽになるようです。

 
最後に、レスポンスが帰ってきた時のコールバック関数も修正します。

void HelloWorld::callback(HttpClient* sender, HttpResponse* response)
{
    std::vector<char>* data = response->getResponseData();
    std::string result(data->begin(), data->end());
    //CCLOG(result.c_str());
    
    Json* json = Json_create(result.c_str());
    
    std::string id = Json_getString(json, "id", "");
    std::string name = Json_getString(json, "name", "");
    
    CCLOG(String::createWithFormat("id:%s , name:%s", id.c_str(), name.c_str())->getCString());
}

今回は、Json_create(result.c_str());Jsonデータを作り、そこからJson_getString()でデータを取り出しています。
Json_getXXX()シリーズは他にもJson_getInt()Json_getFloat()Json_getItem()等があります。
stringintfloatを取り出す時には、第一引数にJsonデータ、第二引数にkey名、第三匹数にデフォルト値を渡します。
getItem()だけは第一引数のJsonデータと第二引数のKey名だけで大丈夫です。
そして、取り出した内容をログに出力しています。
 

これで準備はすべて完了です。


結果

結果というほどの事も無いですが。。。
xcode側のログにcocos2d: id:10 , name:sample-chanと出れば成功です。
結構簡単に出来たので驚いてますが、ここまで出来ればユーザーデータをサーバに保存とか、運営からのお知らせを受信とか、大体の事はできちゃいそうです。 (๑´ڡ`๑)