UE4 Http协议实现Web登陆与注册

一、Http协议

  Http协议网上有很多介绍,这里不过多介绍。需要可以参考

  https://blog.csdn.net/lingxu6/article/details/124738027

二、前期准备

创建UE4 C++项目,在Build.cs中加入模块,UE4需要这些模块才能编译和加载Http和Json格式的数据

using UnrealBuildTool;

public class HttpProject : ModuleRules
{
	public HttpProject(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay","Http","Json", "JsonUtilities","UMG" });
	}
}

三、案例介绍

UE4封装了HttpModule,Json文件的序列化和反序列化,本案例就是使用了这些模块来进行web服务端的通信

服务器返回的数据是Json格式的数据

效果如下:

第一步:创建C++,三个UserWidget,名为StartWidget,RegisterWidget,LoginWidget,

 第二步,创建一个GameMode ,名为StartGameMode

第三步 ,创建UMG,名为BP_MyStart,BP_Register,BP_Login

继承自C++的StartWidget,RegisterWidget,LoginWidget

 

第四步:代码写入StartWidget

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "MyUserWidget.h"
#include "Components/Button.h"
#include "StartWidget.generated.h"

/**
 * 
 */
UCLASS()
class HTTPPROJECT_API UStartWidget : public UMyUserWidget
{
	GENERATED_BODY()
public:
	UPROPERTY()
		UButton* StartButton;
	UPROPERTY()
		UButton* RegisterButton;
	UPROPERTY()
		UButton* QuitButton;

public:
	virtual bool Initialize() override;
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "StartWidget.h"

bool UStartWidget::Initialize()
{
	if (!Super::Initialize())
	{
		return false;
	}
	//初始化开始按钮
	StartButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Start")));
	//初始化注册按钮
	RegisterButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Register")));
	//初始化退出按钮
	QuitButton = Cast<UButton>(GetWidgetFromName(TEXT("Button_Quit")));
	return true;
}

 RegisterWidget代码

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "MyUserWidget.h"
#include "Components/Button.h"
#include "Components/EditableTextBox.h"
#include "Components/TextBlock.h"
#include "HTTP/Public/Interfaces/IHttpRequest.h"
#include "HTTP/Public/Interfaces/IHttpResponse.h"
#include "HTTP/Public/Interfaces/IHttpBase.h"
#include "HTTP/Public/HttpModule.h"
#include "Json/Public/Serialization/JsonWriter.h"
#include "Json/Public/Serialization/JsonReader.h"
#include "Json/Public/Serialization/JsonSerializer.h"
#include "Json/Public/Policies/CondensedJsonPrintPolicy.h"
#include "Json/Public/Dom/JsonObject.h"
#include "RegisterWidget.generated.h"

/**
 * 
 */

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRegisterResultDelegate, bool, result, FString, message);

UCLASS()
class HTTPPROJECT_API URegisterWidget : public UMyUserWidget
{
	GENERATED_BODY()
public:
	
	UPROPERTY()
		UButton* RegisterBtn;
	UPROPERTY()
		UButton* BackBtn;
	UPROPERTY()
		UEditableTextBox* NicknameInput;
	UPROPERTY()
		UEditableTextBox* PasswordInput;
	UPROPERTY()
		UEditableTextBox* RePasswordInput;

	UPROPERTY(BlueprintAssignable, Category = "Register")
		FOnRegisterResultDelegate OnRegisterResultDelegate;
public:
	virtual bool Initialize() override;

	UFUNCTION()
		void RegisterButtonOnClickEvent();
	//注册函数
	void AccountRegisterFromServer(FString nickname,FString password);

private:
	//绑定回调函数
	void RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess);
};

// Fill out your copyright notice in the Description page of Project Settings.


#include "RegisterWidget.h"


bool URegisterWidget::Initialize()
{
	if (!Super::Initialize())
	{
		return false;
	}
	//初始化返回按钮
	BackBtn = Cast<UButton>(GetWidgetFromName(TEXT("Button_Return")));
	//初始化注册按钮
	RegisterBtn = Cast<UButton>(GetWidgetFromName(TEXT("Button_Register")));
	//初始化账号输入框
	NicknameInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_Nickname")));
	//初始化密码输入框
	PasswordInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_Password")));
	//初始化重复密码输入框
	RePasswordInput = Cast<UEditableTextBox>(GetWidgetFromName(TEXT("EditableText_RePassword")));

	//初始化绑定注册函数
	RegisterBtn->OnClicked.AddDynamic(this, &URegisterWidget::RegisterButtonOnClickEvent);
    return true;
}

void URegisterWidget::RegisterButtonOnClickEvent()
{
	FString Account = NicknameInput->GetText().ToString();
	FString PassWord1 = PasswordInput->GetText().ToString();
	FString RePassWord1 = RePasswordInput->GetText().ToString();
	if (Account.Len()< 2 || Account.Len() > 6)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("NickName is too  long"));
		return;
	}
	if (!PassWord1.Equals(RePassWord1))
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Second password is error"));
	}
	AccountRegisterFromServer(Account,PassWord1);
	RegisterBtn->SetIsEnabled(false);
}

void URegisterWidget::AccountRegisterFromServer(FString nickname, FString password)
{
	FString Serverdata;
	TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>::Create(&Serverdata);
	JsonWriter->WriteObjectStart();
	//写入账号
	JsonWriter->WriteValue("nickname", nickname);
	//写入密码
	JsonWriter->WriteValue("password", password);
	//关闭写入
	JsonWriter->WriteObjectEnd();
	//关闭json写入器
	JsonWriter->Close();

	//创建Http 请求
	TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = FHttpModule::Get().CreateRequest();

	//设置Header
	HttpRequest->SetHeader("Content-Type", "application/json;charset=UTF-8");

	HttpRequest->SetVerb("POST");
	//设置请求地址
	HttpRequest->SetURL("https://........................................");
	//设置请求发送的数据
	HttpRequest->SetContentAsString(Serverdata);

	//绑定回调
	HttpRequest->OnProcessRequestComplete().BindUObject(this, &URegisterWidget::RequestComplete);
	//发送请求
	HttpRequest->ProcessRequest();
}


void URegisterWidget::RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess)
{

	UE_LOG(LogTemp, Warning, TEXT(">>request complete"));
	UE_LOG(LogTemp, Warning, TEXT("%s"), *(ResponsePtr->GetContentAsString()));

	if (!EHttpResponseCodes::IsOk(ResponsePtr->GetResponseCode()))
	{
		OnRegisterResultDelegate.Broadcast(false, TEXT("Invalid Network"));
		UE_LOG(LogTemp, Warning, TEXT("Invalid Network"));
		return;
	}
	//创建一个Json解析器
	TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(ResponsePtr->GetContentAsString());
	//创建一个Json对象
	TSharedPtr<FJsonObject> JsonObject;
	//Json反序列化
	bool bIsOk = FJsonSerializer::Deserialize(JsonReader, JsonObject);
	//判断解析是否成功
	if (bIsOk)
	{
		int code = JsonObject->GetIntegerField("code");
		FString msg = JsonObject->GetStringField("msg");
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Msg is : %s"),*msg));
		if (code != 0)
		{
			OnRegisterResultDelegate.Broadcast(false, *msg);
			return;
		}
		TSharedPtr<FJsonObject> DataObject = JsonObject->GetObjectField("data");
		OnRegisterResultDelegate.Broadcast(true, TEXT("Success"));
		UE_LOG(LogTemp, Warning, TEXT("Success"));
	}
}

LoginWidget代码

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LoginActor.generated.h"

UCLASS()
class HTTPPROJECT_API ALoginActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ALoginActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "MyUserWidget.h"
#include "Components/Button.h"
#include "Components/EditableTextBox.h"
#include "Components/TextBlock.h"
#include "HTTP/Public/Interfaces/IHttpRequest.h"
#include "HTTP/Public/Interfaces/IHttpResponse.h"
#include "HTTP/Public/Interfaces/IHttpBase.h"
#include "HTTP/Public/HttpModule.h"
#include "Json/Public/Serialization/JsonWriter.h"
#include "Json/Public/Serialization/JsonReader.h"
#include "Json/Public/Serialization/JsonSerializer.h"
#include "Json/Public/Policies/CondensedJsonPrintPolicy.h"
#include "Json/Public/Dom/JsonObject.h"
#include "LoginWidget.generated.h"

/**
 * 
 */

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnLoginResultDelegate, bool, result, FString, message);

UCLASS()
class HTTPPROJECT_API ULoginWidget : public UMyUserWidget
{
	GENERATED_BODY()
public:
	UPROPERTY()
		UButton* LoginBtn;
	UPROPERTY()
		UButton* ReturnBtn;
	UPROPERTY()
		UEditableTextBox* NicknameInput;
	UPROPERTY()
		UEditableTextBox* PasswordInput;

public:
	virtual bool Initialize() override;

	UPROPERTY(BlueprintAssignable, Category = "Register")
		FOnLoginResultDelegate OnLoginResultDelegate;
	//点击登陆函数
	UFUNCTION()
		void LoginButtonOnClickEvent();
	//登陆方法函数
	void AccountLoginFromServer(FString Nickname,FString Password);


private:
	//绑定回调函数
	void RequestComplete(FHttpRequestPtr RequestPtr, FHttpResponsePtr ResponsePtr, bool bIsSuccess);
};

StartGameMode的代码

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameMode.h"
#include "StartWidget.h"
#include "RegisterWidget.h"
#include "LoginWidget.h"
#include "StartGameMode.generated.h"

/**
 * 
 */
UCLASS()
class HTTPPROJECT_API AStartGameMode : public AGameMode
{
	GENERATED_BODY()
public:
	UPROPERTY()
		UStartWidget* MyStartWidget;
	UPROPERTY()
		URegisterWidget* MyRegisterWidget;

	UPROPERTY()
		ULoginWidget* MyLoginWidget;
		
public:
	virtual void BeginPlay() override;

	UFUNCTION()
		void RegisterBtnOnClickEvent();
	UFUNCTION()
		void RegisterBackBtnOnClickEvent();
	UFUNCTION()
		void StartBtnOnClickEvent();

	UFUNCTION()
		void LoginBackBtnOnClickEvent();

	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "StartGameMode.h"

void AStartGameMode::BeginPlay()
{
	Super::BeginPlay();
	MyStartWidget = CreateWidget<UStartWidget>(GetWorld(),LoadClass<UStartWidget>(nullptr,TEXT("WidgetBlueprint'/Game/BP_Start.BP_Start_C'")));
	if (MyStartWidget)
	{
		MyStartWidget->AddToViewport();
		MyStartWidget->RegisterButton->OnClicked.AddDynamic(this, &AStartGameMode::RegisterBtnOnClickEvent);
		MyStartWidget->StartButton->OnClicked.AddDynamic(this,&AStartGameMode::StartBtnOnClickEvent);
	}
	MyRegisterWidget = CreateWidget<URegisterWidget>(GetWorld(), LoadClass<URegisterWidget>(nullptr, TEXT("WidgetBlueprint'/Game/BP_Register.BP_Register_C'")));
	if (MyRegisterWidget)
	{
		MyRegisterWidget->BackBtn->OnClicked.AddDynamic(this, &AStartGameMode::RegisterBackBtnOnClickEvent);
		
	}
	MyLoginWidget = CreateWidget<ULoginWidget>(GetWorld(), LoadClass<ULoginWidget>(nullptr,TEXT("WidgetBlueprint'/Game/BP_Login.BP_Login_C'")));
	if (MyLoginWidget)
	{
		MyLoginWidget->ReturnBtn->OnClicked.AddDynamic(this, &AStartGameMode::LoginBackBtnOnClickEvent);
	}
}

void AStartGameMode::RegisterBtnOnClickEvent()
{
	MyStartWidget->RemoveFromParent();
	MyRegisterWidget->AddToViewport();
}

void AStartGameMode::RegisterBackBtnOnClickEvent()
{
	MyRegisterWidget->RemoveFromParent();
	MyStartWidget->AddToViewport();
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("RegisterBack"));
}

void AStartGameMode::StartBtnOnClickEvent()
{
	MyStartWidget->RemoveFromParent();
	MyLoginWidget->AddToViewport();
}

void AStartGameMode::LoginBackBtnOnClickEvent()
{
	MyLoginWidget->RemoveFromParent();
	MyStartWidget->AddToViewport();
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("LoginBack"));
}


第五步:世界设置中选中StartGameMode

第六步:测试运行

 到此即可

猜你喜欢

转载自blog.csdn.net/qq_43021038/article/details/126608528