UE5- c++ websocket客户端写法

# 实现目标

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

#实现步骤

  1. {projectName}.Build.cs里增加 "WebSockets","JsonUtilities", "Json"配置信息,最终输出如下:
    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里实现已经生命的方法。

      // 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.

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

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

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

  4. 备注

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

      {"Topic": "Unreal","Data": {"Key": "mood","Value": 1.0}}
  5. 总结

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

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

      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);
  6. 待解决的问题

    1. 为什么使用UGameInstance, UGameInstance在UE5中充当什么角色

    2. ULog 的使用,参考文档:http://www.bimant.com/blog/ue_log-crash-course/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/64774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 快捷键

方法参数顺序快速调整 参数顺序调整 交换参数位置 参数交换位置 编码过程中经常碰到函数调用的参数顺序需要调整的情况。 比如单元测试中&#xff0c;期望和实际值得参数顺序反了&#xff0c;就可以选中参数后或者光标放到要调整的参数位置&#xff0c;然后用 CTRL SHIFTA…

SpringBatch chunk详解

目录 一、Chunk基本概念 1. Chunk的概念: 2. 配置Chunk: 3. Chunk的示例配置: 4. Chunk的执行流程:

maven报错:[ERROR] 不再支持源选项 7。请使用 8 或更高版本。

解决方案 pom.xml文件中增加maven编译的java.version jdk版本设置&#xff0c;以及maven.compiler.source 资源编译jdk版本设置和maven.compiler.target 资源构建jdk版本设置 JDK&#xff1a;6~8 一般都是1.6&#xff0c;1.7&#xff0c;1.8的写法。 <properties><…

前端面试基础面试题——4

1.谈谈你对 ES6 的理解 2.说说你对 promise 的了解 3.解构赋值及其原理 4.Vue常用的修饰符及使用的场景 5.vue 中 key 值的作用 6.什么是 vue 的计算属性&#xff1f; 7.watch的作用是什么 8.计算属性的缓存和方法调用的区别 9.响应式系统的基本原理 10.vue-loader …

基于科大讯飞AIGC创作平台,构建数字人虚拟主播

笔者为体验目前数字人虚拟主播创作视频的质量&#xff0c;特意制作了一段测试视频。 基于讯飞智作创建 总体感受&#xff0c;数字人虚拟主播具有成本低、可定制性强等优点&#xff0c;但是也存在缺乏人情味、技术限制和法律问题等缺点。因此&#xff0c;在使用数字人虚拟主播时…

opencv 提取选中区域内指定hsv颜色的水印

基于《QT 插件化图像算法研究平台》做的功能插件。提取选中区域内指定hsv颜色的水印。 《QT 插件化图像算法研究平台》有个HSV COLOR PICK功能&#xff0c;可以很直观、方便地分析出水印 的hsv颜色&#xff0c;比如, 蓝色&#xff1a;100,180,0,255,100,255。 然后利用 opencv …

QtConcurrent和QFuture的使用

在Qt中&#xff0c;有时候我们会遇到这样一种情况&#xff0c;需要执行一个很长时间的操作&#xff0c;这时候我们的主界面就会卡住。我们的通常做法就是把这个很长时间的操作扔到线程里去处理&#xff0c;可以使用标准库中的线程也可以使用QThread。 如果我们要在这个很长时间…

C# 跨线程访问窗体控件

在不加任何修饰的情况下&#xff0c;C# 默认不允许跨线程访问控件&#xff0c;实际在项目开发过程中&#xff0c;经常使用跨线程操作控件属性&#xff0c;需要设置相关属性才能正确使用&#xff0c;两种方法设置如下&#xff1a; 方法1&#xff1a;告诉编译器取消跨线程访问检…

Springboot GET和POST请求的常用参数获取方式

GET 使用RequestParam注解 可以在控制器方法的参数上使用RequestParam注解来获取请求中的参数值。例如&#xff1a; GetMapping("/example") public String example(RequestParam String param) {// 使用param参数的值return "Value of param: " param…

TDengine函数大全-时序库特有函数

以下内容来自 TDengine 官方文档 及 GitHub 内容 。 以下所有示例基于 TDengine 3.1.0.3 TDengine函数大全 1.数学函数 2.字符串函数 3.转换函数 4.时间和日期函数 5.聚合函数 6.选择函数 7.时序数据库特有函数 8.系统函数 时序库特有函数 TDengine函数大全CSUMDERIVATIVEDIFF…

Android 13.0 Launcher3定制之双层改单层(去掉抽屉式一)

1.概述 在13.0的系统产品开发中,对于在Launcher3中的抽屉模式也就是双层模式,在系统原生的Launcher3中就是双层抽屉模式的, 但是在通过抽屉上滑的模式拉出app列表页,但是在一些产品开发中,对于单层模式的Launcher3的产品模式也是常用的功能, 所以需要了解抽屉模式,然后修…

ModaHub魔搭社区——未来向量数据库会不像传统数据库那样,在国内涌现 200 多家出来?

I. 引言:数据库市场的持续扩张与向量数据库的崛起 随着技术的迭代速度越来越快,技术门槛也在逐渐降低,数据库市场的持续扩张是不可避免的。当前存在着大量的需求,这将吸引越来越多的数据库甚至向量数据库加入竞争。然而,从业界角度看,这种市场扩张是有利的。它可以促使更…

实现公网远程访问:Windows本地快速搭建SFTP文件服务器并配置端口映射

文章目录 1. 搭建SFTP服务器1.1 下载 freesshd服务器软件1.3 启动SFTP服务1.4 添加用户1.5 保存所有配置 2 安装SFTP客户端FileZilla测试2.1 配置一个本地SFTP站点2.2 内网连接测试成功 3 使用cpolar内网穿透3.1 创建SFTP隧道3.2 查看在线隧道列表 4. 使用SFTP客户端&#xff0…

Redis之主从复制解读

目录 基本概述 作用 如何配置主从复制 命令配置&#xff08;Slaveof &#xff09; 配置文件配置 主从复制缺点 主从复制原理 主从复制常见问题解答 命令补充&#xff08;info replication&#xff09; 基本概述 主从复制,是指将一台Redis服务器的数据,复制到其他的R…

Python3 条件控制

Python3 条件控制 Python 条件语句是通过一条或多条语句的执行结果&#xff08;True 或者 False&#xff09;来决定执行的代码块。 可以通过下图来简单了解条件语句的执行过程: 代码执行过程&#xff1a; if 语句 Python中if语句的一般形式如下所示&#xff1a; if conditi…

hadoop的hdfs中避免因节点掉线产生网络风暴

hadoop的hdfs中避免因节点掉线产生网络风暴 控制节点掉线RPC风暴的参数 三个参数都是hdfs-site.xml中参数&#xff0c;具体可以参考apache hadoop官网&#xff0c;其实块的复制速度有两个方面决定&#xff0c;一是namenode分发任务的速度&#xff0c;二则是datanode之间进行复…

python后端,一个账户,多设备登录管理

一个账号&#xff0c;多台设备同时登陆的问题&#xff0c;设计以及实现 参考这篇文章&#xff1a; https://www.alibabacloud.com/help/zh/tair/use-cases/manage-multi-device-logon-from-a-single-user-by-using-tairhash1.0 设计思路 利用的是Redis&#xff0c;主设备的保…

Python文件夹遍历

常用到文件夹遍历操作&#xff0c;会对文件进行如下操作&#xff1a; 文件夹数量文件数量文件类型及各类型数量文件属性&#xff1a;大小、创建日期、最后修改日期 0. 基本分析 使用 os lib import osfrom os.path import join, getsize# yields a 3-tuple dirpath, dirname…

Scala的隐式转换

Scala的隐式转换 隐式转换概念 在 Scala 中&#xff0c;隐式转换&#xff08;Implicit Conversion&#xff09;是一种特性&#xff0c;它允许编译器在需要某种类型时自动进行类型转换。隐式转换的主要作用是增强现有类型的功能或使类型之间的转换更方便。 隐式转换的使用场景…

Android Retrofit 高级使用与原理

简介 在 Android 开发中&#xff0c;网络请求是一个极为关键的部分。Retrofit 作为一个强大的网络请求库&#xff0c;能够简化开发流程&#xff0c;提供高效的网络请求能力。本文将深入介绍 Retrofit 的高级使用与原理&#xff0c;帮助读者更全面地理解和应用这一库。 什么是…