动态库实现lua网络请求GET, POST, 下载文件

DLL需要使用的网络封装

WinHttp异步实现GET, POST, 多线程下载文件_webclient post下载文件-CSDN博客文章浏览阅读726次。基于WinHttp封装, 实现异步多线程文件下载, GET请求, POST请求_webclient post下载文件https://blog.csdn.net/Flame_Cyclone/article/details/142644088

lua_network.h

cpp 复制代码
#pragma once

#include "../common/include/lua.hpp"
#include "lua_utils.h"
#include "Win32Utils/fcjson.h"

class lua_network
{
public:
    static void register_functions(lua_State* L, const char* lib_name);

    static int get(lua_State* L);
    static int post(lua_State* L);
    static int download(lua_State* L);
};

lua_network.cpp

cpp 复制代码
#include "lua_network.h"
#include "lua_utils.h"
#include "Win32Utils/CStrUtils.h"
#include "Win32Utils/CWinHttpClient.h"

static luaL_Reg lib_functions[] =
{
    {"get", lua_network::get},
    {"post", lua_network::post},
    {"download", lua_network::download},
    { NULL, NULL}
};

void lua_network::register_functions(lua_State* L, const char* lib_name)
{
    lua_newtable(L);

    luaL_Reg* fun_info = lib_functions;
    while (fun_info->func)
    {
        lua_pushcfunction(L, fun_info->func);
        lua_setfield(L, -2, fun_info->name);
        fun_info++;
    }
    lua_setfield(L, -2, lib_name);
}

int lua_network::get(lua_State* L)
{
    int nTop = lua_gettop(L);
    _tstring strUrl;
    std::string strParam;
    _tstring strHeader;
    bool fCallback = false;
    int ref = 0;

    if (lua_isfunction(L, -1))
    {
        fCallback = true;
        ref = luaL_ref(L, LUA_REGISTRYINDEX);
    }

    if (nTop >= 1 && lua_isstring(L, 1))
    {
        strUrl = CStrUtils::AStrToTStr(lua_tostring(L, 1));
    }

    if (nTop >= 2)
    {
        if (lua_isstring(L, 2))
        {
            strParam = lua_tostring(L, 2);
        }
        else if (lua_istable(L, 2))
        {
            lua_utils::dump_value(L, strParam, 2, dump_type::dump_get);
        }
    }

    if (nTop >= 3)
    {
        if (lua_isstring(L, 3))
        {
            strHeader = lua_tostring(L, 3);
        }
        else if (lua_istable(L, 3))
        {
            lua_utils::dump_value(L, strHeader, 3, dump_type::dump_header);
        }
    }

    CWinHttpClient obj;

    CWinHttpResult res = obj.Get(strUrl, strParam, strHeader, [&L, ref, fCallback](const WINHTTP_PROGRESS_INFO& progress) -> bool {

        if (fCallback)
        {
            lua_rawgeti(L, LUA_REGISTRYINDEX, ref);

            lua_newtable(L);
            lua_utils::set_key_value(L, "Progress", progress.lfProgress);
            lua_utils::set_key_value(L, "RemainTime", progress.lfRemainTime);
            lua_utils::set_key_value(L, "Speed", progress.lfSpeed);
            lua_utils::set_key_value(L, "Cur", (double)progress.ullCur);
            lua_utils::set_key_value(L, "Total", (double)progress.ullTotal);

            lua_pcall(L, 1, 0, 0);
        }

        return true;
        }
    );

    if (fCallback)
    {
        luaL_unref(L, LUA_REGISTRYINDEX, ref);
    }

    lua_newtable(L);

    lua_utils::set_key_value(L, "code", (lua_Integer)res.code);
    lua_utils::set_key_value(L, "result", CStrUtils::U8StrToAStr(res.result).c_str());

    return 1;
}

int lua_network::post(lua_State* L)
{
    int nTop = lua_gettop(L);
    _tstring strUrl;
    std::string strParam;
    _tstring strHeader;
    bool fCallback = false;
    int ref = 0;

    if (lua_isfunction(L, -1))
    {
        fCallback = true;
        ref = luaL_ref(L, LUA_REGISTRYINDEX);
    }

    if (nTop >= 1 && lua_isstring(L, 1))
    {
        strUrl = CStrUtils::AStrToTStr(lua_tostring(L, 1));
    }

    if (nTop >= 2)
    {
        if (lua_isstring(L, 2))
        {
            strParam = lua_tostring(L, 2);
        }
        else if (lua_istable(L, 2))
        {
            lua_utils::dump_value(L, strParam, 2, dump_type::dump_json);
        }
    }

    if (nTop >= 3)
    {
        if (lua_isstring(L, 3))
        {
            strHeader = lua_tostring(L, 3);
        }
        else if (lua_istable(L, 3))
        {
            lua_utils::dump_value(L, strHeader, 3, dump_type::dump_header);
        }
    }

    CWinHttpClient obj;

    CWinHttpResult res = obj.Post(strUrl, strParam, strHeader, [&L, ref, fCallback](const WINHTTP_PROGRESS_INFO& progress) -> bool {

        if (fCallback)
        {
            lua_rawgeti(L, LUA_REGISTRYINDEX, ref);

            lua_newtable(L);
            lua_utils::set_key_value(L, "Progress", progress.lfProgress);
            lua_utils::set_key_value(L, "RemainTime", progress.lfRemainTime);
            lua_utils::set_key_value(L, "Speed", progress.lfSpeed);
            lua_utils::set_key_value(L, "Cur", (double)progress.ullCur);
            lua_utils::set_key_value(L, "Total", (double)progress.ullTotal);

            lua_pcall(L, 1, 0, 0);
        }

        return true;
        }
    );

    if (fCallback)
    {
        luaL_unref(L, LUA_REGISTRYINDEX, ref);
    }

    lua_newtable(L);

    lua_utils::set_key_value(L, "code", (lua_Integer)res.code);
    lua_utils::set_key_value(L, "result", CStrUtils::U8StrToAStr(res.result).c_str());

    return 1;
}

int lua_network::download(lua_State* L)
{
    int nTop = lua_gettop(L);
    _tstring strUrl;
    _tstring strHeader;
    _tstring strPath;
    bool fCallback = false;
    int ref = 0;

    if (lua_isfunction(L, -1))
    {
        fCallback = true;
        ref = luaL_ref(L, LUA_REGISTRYINDEX);
    }

    if (nTop >= 1 && lua_isstring(L, 1))
    {
        strUrl = CStrUtils::AStrToTStr(lua_tostring(L, 1));
    }

    if (nTop >= 2 && lua_isstring(L, 2))
    {
        strPath = CStrUtils::AStrToTStr(lua_tostring(L, 2));
    }

    if (nTop >= 3)
    {
        if (lua_isstring(L, 3))
        {
            strHeader = lua_tostring(L, 3);
        }
        else if (lua_istable(L, 3))
        {
            lua_utils::dump_value(L, strHeader, 3, dump_type::dump_header);
        }
    }

    CWinHttpClient obj;

    CWinHttpResult res = obj.DownloadFile(strUrl, strPath, strHeader, [&L, ref, fCallback](const WINHTTP_PROGRESS_INFO& progress) -> bool {

        if (fCallback)
        {
            lua_rawgeti(L, LUA_REGISTRYINDEX, ref);

            lua_newtable(L);
            lua_utils::set_key_value(L, "Progress", progress.lfProgress);
            lua_utils::set_key_value(L, "RemainTime", progress.lfRemainTime);
            lua_utils::set_key_value(L, "Speed", progress.lfSpeed);
            lua_utils::set_key_value(L, "Cur", (double)progress.ullCur);
            lua_utils::set_key_value(L, "Total", (double)progress.ullTotal);

            lua_pcall(L, 1, 0, 0);
        }

        return true;
    }
    , std::thread::hardware_concurrency());

    if (fCallback)
    {
        luaL_unref(L, LUA_REGISTRYINDEX, ref);
    }

    lua_newtable(L);
    lua_utils::set_key_value(L, "code", (lua_Integer)res.code);
    lua_utils::set_key_value(L, "result", CStrUtils::U8StrToAStr(res.result).c_str());

    return 1;
}

lua_demo.lua

Lua 复制代码
json = require("JSON")
fclib = require("FCLIB")
lib = nil
--判断当前运行位数
function is64bit()
    arc = os.getenv("PROCESSOR_ARCHITECTURE")
    if arc == "x86" then
        return false
    end
    
    return true
end

--加载动态库
if is64bit() then
    lib = require("lua_library_x64")
else
    lib = require("lua_library_x86")
end

lib.debug.print(lib)

-- 获取弹幕信息
function get_last_msg()

    --请求链接
    url = 'https://api.live.bilibili.com/xlive/web-room/v1/dM/gethistory?roomid=4412054'
    
    -- 参数
    local param = {}

    --请求头
    local header = {
        ['User-Agent']='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0'
    }

    res = lib.network.get(url, param, header)
    lib.debug.print(res)
    
    json_val = lib.json.decode(res.result)
    
    cur_msg = nil
    if json_val then
        for k, v in pairs(json_val['data']['room']) do
            if 0 ~= k then
                cur_msg = v
            end
        end
    end
    
    return cur_msg
end

lib.debug.print(get_last_msg())

function download(info)
    unit = 1024 * 1024
    fmt = '%.2f%% %.3gMB/%.3gMB %.3gMB/s'
    info = string.format(fmt, info['Progress'] * 100, info['Cur'] / unit, info['Total'] / unit, info['Speed'] / unit)
    print(info)
end

--下载链接
download_url = "https://drivers.amd.com/drivers/whql-amd-software-adrenalin-edition-24.8.1-win10-win11-aug-rdna.exe"

file_path = 'whql-amd-software-adrenalin-edition-24.8.1-win10-win11-aug-rdna.exe'

--请求头
header = {
    ['User-Agent']='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0',
    ['Referer']= 'https://www.amd.com/'
}

--下载文件
fResult = lib.network.download(download_url, file_path, header, download)

效果

cpp 复制代码
lua_demo_x64.exe lua_demo.lua

仓库

cpp 复制代码
https://gitee.com/flame_cyclone/lua_example
相关推荐
qq_3227627510 小时前
一个接口从能用到稳定,中间差的到底是什么
服务器·开发语言·lua·接口·fastapi·请求
呆呆敲代码的小Y3 天前
【游戏开发】Lua 与 C# 交互原理解析
c#·lua·交互·热更新·lua与c#交互·游戏热更新
呆呆敲代码的小Y3 天前
Lua 上值(UpValue)
开发语言·junit·lua·lua上值·upvalue
呆呆敲代码的小Y3 天前
【游戏开发】xLua 性能优化技巧
junit·性能优化·lua·xlua
曼巴UE53 天前
Unlua UE5.3 调试
ue5·lua·unlua
nvd113 天前
实战:用 Lua 手写 Kong 安全鉴权插件并通过 ArgoCD GitOps 零编译部署到 DbGate 服务
安全·lua·kong
攻城有术5 天前
专项攻克——redis分布式锁-用LUA脚本解决setNX锁不释放问题
redis·分布式·lua
肠畔码农10 天前
底层视角拆解:Redis Lua脚本原子性、主线程阻塞与主从不一致全解析
java·redis·lua
小的~~12 天前
面试被问懵了?为什么 Redis 单线程还能保证 Lua 脚本原子性,却偏偏选了 Lua?
redis·面试·lua
難釋懷13 天前
Nginx-Lua
nginx·junit·lua