动态库实现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
相关推荐
unix2linux8 小时前
YOLO v5 Series - Image & Video Storage ( Openresty + Lua)
yolo·lua·openresty
最后一个bug9 小时前
如何理解Lua 使用虚拟堆栈
linux·c语言·开发语言·嵌入式硬件·lua
半夏知半秋2 天前
lua-lru缓存算法解析
笔记·学习·算法·缓存·lua
最后一个bug2 天前
C语言执行Lua进行错误处理
linux·服务器·c语言·开发语言·嵌入式硬件·lua
袁庭新2 天前
Lua如何连接MySQL数据库?
redis·mysql·lua·lua5.4·袁庭新
红黑色的圣西罗2 天前
Lua 实现继承的一种方式
开发语言·lua
weixin_428498494 天前
Lua资料
开发语言·lua
Clown954 天前
go-zero(四) 错误处理(统一响应信息)
开发语言·golang·lua
半夏知半秋5 天前
lua实现雪花算法
开发语言·笔记·算法·lua
最后一个bug5 天前
lua调用C语言函数,在函数中进行类型检查
linux·c语言·开发语言·lua