http网络编程——在ue5中实现文件传输功能

http网络编程在ue5中实现

需求:在unreal中实现下载功能,输入相关url网址,本地文件夹存入相应文件。

一、代码示例

1.Build.cs需要新增Http模块,样例如下。

cpp 复制代码
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP" });

2.RuntimeFilesDownloaderLibrary.h文件

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.
 
#pragma once
 
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "Interfaces/IHttpRequest.h"
#include "RuntimeFilesDownloaderLibrary.generated.h"
 
UENUM(BlueprintType, Category = "Runtime Files Downloader")
enum DownloadResult
{
    SuccessDownloading UMETA(DisplayName = "Success"),
    DownloadFailed UMETA(DisplayName = "Download failed"),
    SaveFailed UMETA(DisplayName = "Save failed"),
    DirectoryCreationFailed UMETA(DisplayName = "Directory creation failed")
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnFilesDownloaderProgress, const int32, BytesSent, const int32, BytesReceived, const int32, ContentLength);

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFilesDownloaderResult, TEnumAsByte < DownloadResult >, Result);
 
UCLASS()
class DOWNLOAD_API URuntimeFilesDownloaderLibrary : public UObject
{
    GENERATED_BODY()
public:
    UPROPERTY(BlueprintAssignable, Category = "Runtime Files Downloader")
        FOnFilesDownloaderProgress OnProgress;

    UPROPERTY(BlueprintAssignable, Category = "Runtime Files Downloader")
        FOnFilesDownloaderResult OnResult;
 
    UPROPERTY(BlueprintReadOnly, Category = "Runtime Files Downloader")
        FString FileURL;
 
    UPROPERTY(BlueprintReadOnly, Category = "Runtime Files Downloader")
        FString FileSavePath;
 
    UFUNCTION(BlueprintCallable, Category = "Runtime Files Downloader")
        static URuntimeFilesDownloaderLibrary* CreateDownloader();
 
    UFUNCTION(BlueprintCallable, Category = "Runtime Files Downloader")
        bool DownloadFile(const FString& URL, const FString& SavePath, float TimeOut = 5);
private:
    void OnProgress_Internal(FHttpRequestPtr Request, int32 BytesSent, int32 BytesReceived);
 
    void OnReady_Internal(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
};

3.RuntimeFilesDownloaderLibrary.cpp文件

cpp 复制代码
#include "RuntimeFilesDownloaderLibrary.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
//创建了一个URuntimeFilesDownloaderLibrary对象,并将其添加到根对象,防止系统自动回收
URuntimeFilesDownloaderLibrary* URuntimeFilesDownloaderLibrary::CreateDownloader()
{
    URuntimeFilesDownloaderLibrary* Downloader = NewObject<URuntimeFilesDownloaderLibrary>();
    Downloader->AddToRoot();
    return Downloader;
}
 
bool URuntimeFilesDownloaderLibrary::DownloadFile(const FString& URL, const FString& SavePath, float TimeOut)
{
    if (URL.IsEmpty() || SavePath.IsEmpty() || TimeOut <= 0)
    {
        return false;
    }
 
    FileURL = URL;
    FileSavePath = SavePath;
    /*ue4.27旧版本弃用下列方法*/
    /*TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();*/
 
    //4.27及以后使用如下方法
    TSharedPtr<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();
 
    HttpRequest->SetVerb("GET");
    HttpRequest->SetURL(FileURL);
    //HttpRequest->SetTimeout(TimeOut);
    //监听事件OnProcessRequestComplete绑定OnReady_Internal,OnRequestProgress绑定OnProgress_Internal
    HttpRequest->OnProcessRequestComplete().BindUObject(this, &URuntimeFilesDownloaderLibrary::OnReady_Internal);
    HttpRequest->OnRequestProgress().BindUObject(this, &URuntimeFilesDownloaderLibrary::OnProgress_Internal);
 
    // Process the request
    HttpRequest->ProcessRequest();
 
    return true;
}
    //监听事件
void URuntimeFilesDownloaderLibrary::OnProgress_Internal(FHttpRequestPtr Request, int32 BytesSent, int32 BytesReceived)
{
    const FHttpResponsePtr Response = Request->GetResponse();
    if (Response.IsValid())
    {
        const int32 FullSize = Response->GetContentLength();
        OnProgress.Broadcast(BytesSent, BytesReceived, FullSize);
    }
}
 
void URuntimeFilesDownloaderLibrary::OnReady_Internal(FHttpRequestPtr Request, FHttpResponsePtr Response,
    bool bWasSuccessful)
{
RemoveFromRoot();
    Request->OnProcessRequestComplete().Unbind();
 
    if (Response.IsValid() && EHttpResponseCodes::IsOk(Response->GetResponseCode()) && bWasSuccessful)
    {
        //
        IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
 
        // 
        FString Path, Filename, Extension;
        FPaths::Split(FileSavePath, Path, Filename, Extension);
        //查看文件夹,没有则创建文件
        if (!PlatformFile.DirectoryExists(*Path))
        {
            if (!PlatformFile.CreateDirectoryTree(*Path))
            {
                OnResult.Broadcast(DirectoryCreationFailed);
                return;
            }
        }
 
        // 开启文件写入
        //通过PlatformFile.OpenWrite()函数打开文件句柄,以便将下载的数据写入文件中。函数的参数是一个TCHAR类型的字符串,表示文件的路径和文件名。
        //然后,检查句柄是否成功打开。如果句柄成功打开,就将HTTP请求响应中的数据通过FileHandle->Write()函数写入到文件中。
        IFileHandle* FileHandle = PlatformFile.OpenWrite(*FileSavePath);
        if (FileHandle)
        {
            // 
            FileHandle->Write(Response->GetContent().GetData(), Response->GetContentLength());
            // 
            delete FileHandle;
 
            OnResult.Broadcast(SuccessDownloading);
        }
        else
        {
            OnResult.Broadcast(SaveFailed);
        }
    }
    else
    {
        OnResult.Broadcast(DownloadFailed);
    }
}

二、蓝图示例


该蓝图在关卡中调用,通过Event Begin Play事件监听行为,当按下

按钮,创建DOWNLOADER对象,并执行下载功能,下载时对下载行为进行监听,包括RESULT(Success,Download failed,Save failed,Directory creation failed四种下载结果)和以下三个数据信息:

· BytesSent 表示已发送的字节数,指示已经发送到服务器的字节数。

· BytesReceived 表示已接收的字节数,指示已从服务器接收到的字节数。

· FullSize 表示完整内容的长度,指示需要下载的文件的总字节数。

最后通过BytesReceived/FullSize计算出百分号数据,实现下载进度实时追踪,下载完成后RESULT枚举信息输出。

三、效果展示

在蓝图中输入url和save path相关信息,time out为响应时间设置。

下载过程实现监听,下载完成后输出RESULT枚举类型。

最后本地文件夹成功下载http文件。

相关推荐
YWamy7 小时前
如何降低RTC SDK在复杂网络环境下的运行成本
网络·音视频·实时音视频
北京盛世宏博7 小时前
信创国产化智慧档案馆管库系统:十二防一体化管控平台落地笔记
网络·方案·温湿度·智慧档案馆建设
w-w0w-w8 小时前
SQL注入
网络·数据库·sql
一条泥憨鱼8 小时前
【计算机网络】短连接、长连接与连接池:从 TCP 握手到池化复用的完整链路
网络·数据库·网络协议·tcp/ip·计算机网络
北京盛世宏博8 小时前
数字孪生 3D 可视化实战:档案十防体系温湿度数据联动与告警定位实现
网络·档案八防·十防
Lynne3099 小时前
EtherCAT网络中,多个节点如何配置才能互不干扰?
网络·网络配置·ethercat·工业网络
Yang961110 小时前
实验室里的多面手:鼎讯信通TM-150信号发生器技术拆解与实测思考
网络
cyf3110 小时前
第 05 篇:IP 协议—— 网络层的“快递单号与物流追踪“
网络协议·tcp/ip·路由表·traceroute·ip协议·ping·ip分片
默|笙12 小时前
【Linux网络】传输层协议TCP(1)---TCP报文介绍
linux·网络·tcp/ip