UE5- c++ websocket客户端写法

# 实现目标

  • ue5 c++ 实现socket客户端,读取服务端数据,并进行解析

#实现步骤

  1. {projectName}.Build.cs里增加 "WebSockets","JsonUtilities", "Json"配置信息,最终输出如下:

    cpp 复制代码
    using UnrealBuildTool;
    
    public class myue521 : ModuleRules
    {
    	public myue521(ReadOnlyTargetRules Target) : base(Target)
    	{
    		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
    
    		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore"
            , "HeadMountedDisplay", "EnhancedInput"
            , "WebSockets","JsonUtilities", "Json"});
    	}
    }

    说明,其中myue521是我的模块名,文件名为myue521.Build.cs。 新增的模块:"WebSockets","JsonUtilities", "Json"。

  2. 准备实现自己的webscoket_client。具体操作步骤如下:

    1. 在ue5中自定义类,父类设置为UGameInstance,我这命名为UUWebSocketGameInstance

    2. 在UUWebSocketGameInstance.h里新增如下方法。

      1. 其中init和 Shutdown方法是在父类UGameInstance中定义的,我们这里覆盖它;

      2. WebSocket用来标识我们代码生成的socket,计划在init里初始化,在Shutdown里销毁

      3. OnConnected、OnConnectionError、OnClosed、OnMessage、OnMessageSent用来处理socket消息,具体看后买你的代码实现。

    3. 在UUWebSocketGameInstance.cpp里实现已经生命的方法。

      cpp 复制代码
      // Fill out your copyright notice in the Description page of Project Settings.
      
      
      #include "UWebSocketGameInstance.h"
      #include "WebSockets/Public/WebSocketsModule.h"
      #include "WebSockets/Public/IWebSocket.h"
      #include "Templates/SharedPointer.h"
      
      
      void UUWebSocketGameInstance::Init() {
      	Super::Init();
      
      	if (!FModuleManager::Get().IsModuleLoaded("WebSockets")) {
      		FModuleManager::Get().LoadModule("WebSockets");
      	}
      
      	WebSocket = FWebSocketsModule::Get().CreateWebSocket("ws://127.0.0.1:8081/webSocketServer/ue");
      	 
      	WebSocket->OnConnected().AddUObject(this, &UUWebSocketGameInstance::OnConnected);
      	WebSocket->OnConnectionError().AddUObject(this, &UUWebSocketGameInstance::OnConnectionError);
      	WebSocket->OnClosed().AddUObject(this, &UUWebSocketGameInstance::OnClosed);
      	WebSocket->OnMessage().AddUObject(this, &UUWebSocketGameInstance::OnMessage);
      	WebSocket->OnMessageSent().AddUObject(this, &UUWebSocketGameInstance::OnMessageSent);
      
      	WebSocket->Connect();
      
      }
       
      
      void UUWebSocketGameInstance::Shutdown() {
      
      	if (WebSocket->IsConnected()) {
      		WebSocket->Close();
      	} 
      	Super::Shutdown();
      }
      
      
      
      void UUWebSocketGameInstance::OnConnected()
      {
      	UE_LOG(LogTemp, Warning, TEXT("%s"), *FString(__FUNCTION__));
      
      	GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Green, "Successfully Connected");
      }
      
      void UUWebSocketGameInstance::OnConnectionError(const FString& Error)
      {
      	UE_LOG(LogTemp, Warning, TEXT("%s Error:%s"), *FString(__FUNCTION__), *Error);
      }
      
      void UUWebSocketGameInstance::OnClosed(int32 StatusCode, const FString& Reason, bool bWasClean)
      {
      	UE_LOG(LogTemp, Warning, TEXT("%s StatusCode:%d Reason:%s bWasClean:%d"),
      		*FString(__FUNCTION__), StatusCode, *Reason, bWasClean);
      }
      
      void UUWebSocketGameInstance::OnMessage(const FString& Message)
      {
      	GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Cyan, FString::Printf(TEXT("%s Message:%s"), *FString(__FUNCTION__), *Message) );
      
      	UE_LOG(LogTemp, Warning, TEXT("%s Message:%s"), *FString(__FUNCTION__), *Message);
      
      	TSharedRef< TJsonReader<> > Reader = TJsonReaderFactory<>::Create(Message);
      	TSharedPtr<FJsonObject> Root;
      
      	if (FJsonSerializer::Deserialize(Reader, Root))
      	{
      		if (Root->HasField(TEXT("Topic"))) {
      			FString Topic = Root->GetStringField(TEXT("Topic"));
      			TSharedPtr<FJsonObject, ESPMode::ThreadSafe> Data = Root->GetObjectField(TEXT("Data"));
      
      			// TSharedPtr<FJsonObject, ESPMode::ThreadSafe> ObjectField = Object->GetObjectField(TEXT("realtime"));
      			FString KeyField = Data->GetStringField("Key");
      			FString ValueField = Data->GetStringField("Value");
      
      
      			GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Cyan, "Key: " + KeyField + ",Value:" + ValueField);
      		}
      		else {
      			GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Cyan, "解析json异常");
      		}
      	}
      }
      
      void UUWebSocketGameInstance::OnMessageSent(const FString& MessageString)
      {
      	UE_LOG(LogTemp, Warning, TEXT("%s MessageString:%s"), *FString(__FUNCTION__), *MessageString);
      }
      1. 其中UUWebSocketGameInstance::Init()里初始化了websocket,并配置监听方法

      2. UUWebSocketGameInstance::Shutdown()用来销毁生成的websocket

      3. UUWebSocketGameInstance::OnConnected(),UUWebSocketGameInstance::OnConnectionError,UUWebSocketGameInstance::OnClosed,UUWebSocketGameInstance::OnMessage,UUWebSocketGameInstance::OnMessageSent是用来处理绑定消息的。其中UUWebSocketGameInstance::OnMessage里的消息是json格式,具体格式见下面的备注1.

开始配置使用并调用方法。

  1. 自主调用可以在某个Character里通过如下代码进行调用。可以在自己的类里面调用。比如放到构造方法或者某个动作触发调用。

    cpp 复制代码
    void Amyue521Character::NotifyServer() {
    	UUWebSocketGameInstance* GameInstance = Cast<UUWebSocketGameInstance>(GetGameInstance());
    	if (GameInstance) {
    		if (GameInstance->WebSocket->IsConnected()) {
    			GameInstance->WebSocket->Send("FROM UnrealEngine 5");
    		}
    	}
    }
  2. 通过UE5的项目设置进行修改游戏实例。

备注

  1. 约定接收的json数据格式为

    复制代码
    {
        "Topic": "Unreal",
        "Data": {
            "Key": "mood",
            "Value": 1.0
        }
     }

总结

  1. 通过该例子我们学到了websocket,json的应用

  2. 还学到的两种打印log的方法

    cpp 复制代码
    GEngine->AddOnScreenDebugMessage(-1, 3.0f, FColor::Cyan, FString::Printf(TEXT("%s Message:%s"), *FString(__FUNCTION__), *Message) );
    
    UE_LOG(LogTemp, Warning, TEXT("%s Message:%s"), *FString(__FUNCTION__), *Message);

待解决的问题

  1. 为什么使用UGameInstance, UGameInstance在UE5中充当什么角色
相关推荐
mengzhi啊2 天前
ue5 在一个蒙太奇的上半身插槽放两段动画,用片段1,2作为区分。播放动画蒙太奇,自由选择片段1,2
ue5
子燕若水3 天前
UE5 开启“Python Remote Execution“
ue5
我要吐泡泡了哦3 天前
虚幻5路径追踪渲染器(PT和DF的效果差别与PT速度性能)-李文磊-技术分享笔记
笔记·ue5·图形渲染
ue星空9 天前
模之屋模型导入到UE5
ue5·蓝图
mengzhi啊9 天前
ue5 设置角色属性(生命值,蓝条值,能量值)c++
ue5
ue星空9 天前
UE5游戏性能优化指南
游戏·性能优化·ue5·蓝图
电子云与长程纠缠10 天前
在UE5中使用视差贴图
学习·缓存·ue5·编辑器·贴图
子燕若水10 天前
Unreal Engine 5 (UE5) Metahuman 的头部材质
前端·ue5·材质
ue星空10 天前
UE材质节点Fresnel
ue5·材质
ue星空11 天前
UE材质控制UV
ue5·材质·uv