cocos2dx-lua用原生httpClient实现http请求

如题,最近cocos2dx-lua项目用到http里请求。quick的话可以用network.createHTTPRequest实现,我们的项目是直接用2dx原生创建的lua项目,没有quick的部分。百度了下,发现可以用cc.XMLHttpRequest来实现http请求,然而我在调用cc.XMLHttpRequest却报错说XMLHttpRequest为nil,具体原因还没看,不过看代码2dx是绑定了这个类的。于是我打算重写一个类,用httpClient原生实现http请求,并进行lua绑定。

导航:主要看2,3,4,6(2,3为主要代码,4就一句话,6为lua最后调用代码)。

---------------1.新建lua_tool.hpp和lua_tool.cpp

--------1.1新建文件夹luaTool

完整路径为frameworks->cocos2d-x->cocos->scripting->lua-bindings->luaTool,luaTool为新建的文件夹。

--------1.2新建lua_tool.hpp

文件夹luaTool下新建lua_tool.hpp文件,完整路径为frameworks->cocos2d-x->cocos->scripting->lua-bindings->luaTool->lua_tool.hpp

--------1.3新建lua_tool.cpp

文件夹luaTool下新建lua_tool.cpp文件,完整路径为frameworks->cocos2d-x->cocos->scripting->lua-bindings->luaTool->lua_tool.cpp

---------------2.lua_tool.hpp完整代码

/*
 *Evan
 */
#include "base/ccConfig.h"
#ifndef __lua_tool_h__
#define __lua_tool_h__

#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif

#include "cocos-ext.h"
#include "network/HttpClient.h"
#include "network/HttpResponse.h"

USING_NS_CC;
USING_NS_CC_EXT;
using namespace network;
using namespace std;

class LuaHttp
{
public:
    LuaHttp();
    ~LuaHttp();
    
    void setLuaCallBack(int _luaCallBack);
    void sendGet(const char* url, const char* data);
    void sendPost(const char* url, const char* data);
    void loadImage(const char* url);
    void onRequestComplete(HttpClient *sender, HttpResponse *response);
    void onRequestImageComplete(HttpClient *sender, HttpResponse *response);
private:
    int luaCallBack;

};

int register_all_luaTool(lua_State* tolua_S);
---------------3.lua_tool.cpp完整代码

/*
 *Evan
 */
#include "lua_tool.hpp"
#include <string>
//#include "ccUTF8.h"
#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
#include "scripting/lua-bindings/manual/CCLuaValue.h"
#include "scripting/lua-bindings/manual/CCLuaStack.h"
#include "scripting/lua-bindings/manual/CCLuaEngine.h"

/******************************************************************************
 *******************************     C++ CODE    ******************************
 ******************************************************************************/

LuaHttp::LuaHttp()
:luaCallBack(0)
{
}

LuaHttp::~LuaHttp()
{
    if (luaCallBack)
    {
        LuaEngine::getInstance()->removeScriptHandler(luaCallBack);
    }
}

void LuaHttp::setLuaCallBack(int _luaCallBack)
{
    luaCallBack = _luaCallBack;
}

void LuaHttp::sendGet(const char* url, const char* data){
    HttpRequest* request  = new HttpRequest();
    string _url = StringUtils::format("%s?%s", url, data);
    request->setUrl(_url.c_str());
    request->setRequestType(HttpRequest::Type::GET);
    request->setResponseCallback(CC_CALLBACK_2(LuaHttp::onRequestComplete, this));
    request->setTag("GET REQUEST");
    HttpClient::getInstance()->send(request);
    request->release();
}

void LuaHttp::sendPost(const char* url, const char* data){
    HttpRequest* request = new HttpRequest();
    request->setUrl(url);
    request->setRequestType(HttpRequest::Type::POST);
    request->setResponseCallback(CC_CALLBACK_2(LuaHttp::onRequestComplete, this));

    // write the post data
    request->setRequestData(data, strlen(data));
    request->setTag("POST REQUEST");
    //HttpClient::getInstance()->setTimeoutForConnect(10);
    HttpClient::getInstance()->send(request);
    request->release();
}

void LuaHttp::onRequestComplete(HttpClient *sender, HttpResponse *response){
    if (!response)
    {
        log("LuaHttp::onRequestComplete response is null");

        //lua callBack
        if (luaCallBack)
        {
            LuaValueDict dict;
            
            dict["code"] = LuaValue::intValue(9999);
            
            LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
            stack->clean();
            stack->pushLuaValueDict(dict);
            stack->executeFunctionByHandler(luaCallBack, 1);
        }
        return;
    }
    if (0 != strlen(response->getHttpRequest()->getTag()))
    {
        log("LuaHttp::onRequestComplete %s complete", response->getHttpRequest()->getTag());
    }
    
    int statusCode = (int)response->getResponseCode();
    const char* flag = response->getHttpRequest()->getTag();
    string statusString = StringUtils::format("Http Request Code: %d  tag = %s", statusCode, flag);
    log("LuaHttp::onRequestComplete statusString:%s", statusString.c_str());
    
    //special error code
    if (statusCode == 503 || statusCode == 500 || (statusCode != -1 && statusCode != 404/* && statusCode != 500*/ && statusCode != 200))
    {
        log("LuaHttp::onRequestComplete response failed!  statusCode == 503 || statusCode == 500");
//        log("HNManager::onHttpRequestComplete error buffer:%s  statusCode == 503", response->getErrorBuffer());
//        return;
    }
    
    if (!response->isSucceed())
    {
        log("LuaHttp::onRequestComplete response failed!");
        log("LuaHttp::onRequestComplete error buffer:%s", response->getErrorBuffer());
        
        //lua callBack
        if (luaCallBack)
        {
            LuaValueDict dict;
            
            dict["code"] = LuaValue::intValue((int)response->getResponseCode());
            dict["tag"] = LuaValue::stringValue(response->getHttpRequest()->getTag());
            
            LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
            stack->clean();
            stack->pushLuaValueDict(dict);
            stack->executeFunctionByHandler(luaCallBack, 1);
        }
        return;
    }

    // dump data
    vector<char>* buffer = response->getResponseData();
    string result;
    for(vector<char>::iterator iter = buffer->begin(); iter != buffer->end(); ++iter)
    {
        result += *iter;
    }
    log("LuaHttp::onRequestComplete  server result:%s", result.c_str());
    
    //lua callBack
    if (luaCallBack)
    {
        LuaValueDict dict;
        
        dict["code"] = LuaValue::intValue((int)response->getResponseCode());
        dict["tag"] = LuaValue::stringValue(response->getHttpRequest()->getTag());
        dict["result"] = LuaValue::stringValue(result);
//        dict["request"] = LuaValue::ccobjectValue(this, "HTTPRequest");
        
        LuaStack *stack = LuaEngine::getInstance()->getLuaStack();
        stack->clean();
        stack->pushLuaValueDict(dict);
        stack->executeFunctionByHandler(luaCallBack, 1);
    }
}

/******************************************************************************
 ****************************     LUA-BINDING    ******************************
 ******************************************************************************/
static int lua_tool_LuaHttp_constructor(lua_State* L)
{
    int argc = 0;
    LuaHttp* self = nullptr;
    
#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif
    
    argc = lua_gettop(L)-1;
    if (argc == 0)
    {
        self = new (std::nothrow) LuaHttp();
        tolua_pushusertype(L, (void*)self, "lt.LuaHttp");
        tolua_register_gc(L, lua_gettop(L));
        return 1;
    }
    
    luaL_error(L, "%s has wrong number of arguments: %d, was expecting %d \n", "LuaHttp",argc, 0);
    return 0;
    
#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(L,"#ferror in function 'lua_tool_LuaHttp_constructor'.",&tolua_err);
    return 0;
#endif
}

int lua_tool_LuaHttp_sendGet(lua_State* tolua_S)
{
    int argc = 0;
    LuaHttp* cobj = nullptr;
    bool ok  = true;
    
#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif
    
    
#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(tolua_S,1,"lt.LuaHttp",0,&tolua_err)) goto tolua_lerror;
#endif
    
    cobj = (LuaHttp*)tolua_tousertype(tolua_S,1,0);
    
#if COCOS2D_DEBUG >= 1
    if (!cobj)
    {
        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_tool_LuaHttp_sendGet'", nullptr);
        return 0;
    }
#endif
    
    argc = lua_gettop(tolua_S)-1;
    
    do
    {
        if (argc == 1)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2,&arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            cobj->sendGet(arg0.c_str(), "");
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    do
    {
        if (argc == 2)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2, &arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            std::string arg1;
            ok &= luaval_to_std_string(tolua_S, 3, &arg1, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            cobj->sendGet(arg0.c_str(), arg1.c_str());
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    do
    {
        if (argc == 3)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2, &arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            std::string arg1;
            ok &= luaval_to_std_string(tolua_S, 3, &arg1, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            LUA_FUNCTION callBack = (toluafix_ref_function(tolua_S, 4, 0));
            cobj->sendGet(arg0.c_str(), arg1.c_str());
            cobj->setLuaCallBack(callBack);
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "lt.LuaHttp:sendGet",argc, 1);
    return 0;
    
#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_tool_LuaHttp_sendGet'.",&tolua_err);
#endif
    
    return 0;
}

int lua_tool_LuaHttp_sendPost(lua_State* tolua_S)
{
    int argc = 0;
    LuaHttp* cobj = nullptr;
    bool ok  = true;
    
#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif
    
    
#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(tolua_S,1,"lt.LuaHttp",0,&tolua_err)) goto tolua_lerror;
#endif
    
    cobj = (LuaHttp*)tolua_tousertype(tolua_S,1,0);
    
#if COCOS2D_DEBUG >= 1
    if (!cobj)
    {
        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_tool_LuaHttp_sendGet'", nullptr);
        return 0;
    }
#endif
    
    argc = lua_gettop(tolua_S)-1;
    
    do
    {
        if (argc == 1)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2,&arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            cobj->sendGet(arg0.c_str(), "");
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    do
    {
        if (argc == 2)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2, &arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            std::string arg1;
            ok &= luaval_to_std_string(tolua_S, 3, &arg1, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            cobj->sendGet(arg0.c_str(), arg1.c_str());
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    do
    {
        if (argc == 3)
        {
            std::string arg0;
            ok &= luaval_to_std_string(tolua_S, 2, &arg0, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            std::string arg1;
            ok &= luaval_to_std_string(tolua_S, 3, &arg1, "lt.LuaHttp:sendGet");
            if (!ok) { break; }
            LUA_FUNCTION callBack = (toluafix_ref_function(tolua_S, 4, 0));
            cobj->sendPost(arg0.c_str(), arg1.c_str());
            cobj->setLuaCallBack(callBack);
            lua_settop(tolua_S, 1);
            return 1;
        }
    } while (0);
    ok  = true;
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "lt.LuaHttp:sendGet",argc, 1);
    return 0;
    
#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_tool_LuaHttp_sendGet'.",&tolua_err);
#endif
    
    return 0;
}

int lua_register_luaTool_LuaHttp(lua_State* tolua_S)
{
    tolua_usertype(tolua_S, "lt.LuaHttp");
    tolua_cclass(tolua_S, "LuaHttp","lt.LuaHttp", "", nullptr);
    
    tolua_beginmodule(tolua_S, "LuaHttp");
    tolua_function(tolua_S, "new", lua_tool_LuaHttp_constructor);
    tolua_function(tolua_S, "sendGet", lua_tool_LuaHttp_sendGet);
    tolua_function(tolua_S, "sendPost", lua_tool_LuaHttp_sendPost);
    tolua_endmodule(tolua_S);
    std::string typeName = typeid(LuaHttp).name();
    g_luaType[typeName] = "lt.LuaHttp";
    g_typeCast["LuaHttp"] = "lt.LuaHttp";
    return 1;
}

TOLUA_API int register_all_luaTool(lua_State* tolua_S)
{
    tolua_open(tolua_S);
    
    tolua_module(tolua_S,"lt",0);
    tolua_beginmodule(tolua_S,"lt");
    
    lua_register_luaTool_LuaHttp(tolua_S);
    
    tolua_endmodule(tolua_S);
    return 1;
}

说明:这里我没用cocos通用的cc开头,而用了lt(luatool的意思),看个人爱好。

---------------4.注册lua绑定

--------4.1调用register_all_luaTool(_state);
frameworks->cocos2d-x->cocos->scripting->lua-bindings->manual->CCLuaStack.cpp中的boolLuaStack::init(void)方法中在

register_all_cocos2dx(_state);下面添加register_all_luaTool(_state);

-----4.2添加头文件

#include "scripting/lua-bindings/luaTool/lua_tool.hpp"

---------5.项目中添加lua_tool.hpp和lua_tool.cpp

-----5.1 New Group

项目->cocos2d_lua_bindings.xcodeproj->右键->New Group->命名为luaTool

-----5.2 Add Files To ...

项目->cocos2d_lua_bindings.xcodeproj->luaTool->右键->Add Files To ...,选择lua_tool.hpp和lua_tool.cpp所在位置。

-----5.3勾选libluacocos2d iOS

选中刚刚添加的两个文件,Xcode右侧->TargetMembership->勾选libluacocos2d iOS。否则在移动端还是没编译这两个文件。

---------6.lua调用

    local callBack = function (request)
        print("返回 返回 code : ", request.code)
        print("返回 返回 tag : ", request.tag)
        print("返回 返回 result : ", request.result)
    end
    local luaHttp = lt.LuaHttp:new()
    -- luaHttp:sendGet("https://www.baidu.com/","", callBack)
    luaHttp:sendPost("https://www.baidu.com/","", callBack)

---------------7.添加完register_all_luaTool(_state );后的LuaStack::init方法
bool LuaStack::init(void)
{
    _state = lua_open();
    luaL_openlibs(_state);
    toluafix_open(_state);

    // Register our version of the global "print" function
    const luaL_reg global_functions [] = {
        {"print", lua_print},
        {"release_print",lua_release_print},
        {nullptr, nullptr}
    };
    luaL_register(_state, "_G", global_functions);

    g_luaType.clear();
    register_all_cocos2dx(_state);
    register_all_luaTool(_state);
    tolua_opengl_open(_state);
    register_all_cocos2dx_manual(_state);
    register_all_cocos2dx_module_manual(_state);
    register_all_cocos2dx_math_manual(_state);
    register_all_cocos2dx_experimental(_state);
    register_all_cocos2dx_experimental_manual(_state);

    register_glnode_manual(_state);
#if CC_USE_PHYSICS
    register_all_cocos2dx_physics(_state);
    register_all_cocos2dx_physics_manual(_state);
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
    LuaObjcBridge::luaopen_luaoc(_state);
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    LuaJavaBridge::luaopen_luaj(_state);
#endif
    register_all_cocos2dx_deprecated(_state);
    register_all_cocos2dx_manual_deprecated(_state);

    tolua_script_handler_mgr_open(_state);

    // add cocos2dx loader
    addLuaLoader(cocos2dx_lua_loader);

    return true;
}

---------------8.Android.mk

若在Android平台运行,则需要修改对应的Android.mk文件。frameworks->cocos2d-x->cocos->scripting->lua-bindings->proj.android->Android.mk,大概65行的位置,在../manual/tolua_fix.cpp \下面添加代码:../luaTool/lua_tool.cpp \

--------9.其他

其中请求返回的callBack参数可以随便添加,仿照c++代码调用luaCallBack时的LuaValueDict即可(dict["xxx"] = xxx),类型自己点进去看看就行了。

--------10.虽然报nil,但最后还是列出XMLHttpRequest实现http请求的方法。

      -- local xhr = cc.XMLHttpRequest:new() -- http请求
      -- xhr.responseType = cc.XMLHTTPREQUEST_RESPONSE_STRING -- 响应类型
      -- xhr:open("GET", "https://www.baidu.com/") -- 打开链接
 
      -- -- 状态改变时调用
      -- local function onReadyStateChange()
      --   -- 显示状态文本
      --   -- local statusString = "Http Status Code:"..xhr.statusText
      --   -- labelStatusCode:setString(statusString)
      --   print(xhr.response)

      --     -- 显示状态码,成功显示200
      --   -- labelStatusCode:setString("Http Status Code:"..xhr.statusText)
      --   -- local response   = xhr.response -- 获得响应数据
      --   -- local output = json.decode(response,1) -- 解析json数据
      --   -- table.foreach(output,function(i, v) print (i, v) end)
      --   -- print("headers are")
      --   -- table.foreach(output.headers,print)
      -- end
 
      -- -- 注册脚本回调方法
      -- xhr:registerScriptHandler(onReadyStateChange)
      -- xhr:send() -- 发送请求






  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值