【Unity/网络】Unity和内网穿透的网络测试 —— 以聊天室为例

这两天在做那个CodeMonky的胡闹厨房的案例,一直困扰我的是关于Lobby和Relay的相关网络服务,需要挂加速器并且延迟不低,所以我一直在寻找一些其他替代方案,想起来之前做一个UEC++的网络枪战时做过一个内网穿透的方法,所以在Unity中也采用这个方案,但中间怎么改IP和端口都没法连接成功,最后就索性单开了一个项目来测试这一块,现在也算是测出来原因了,这里写个笔记记录下过程

左客户端,右主机端

文章目录

    • 案例概述
    • 关键代码部分
      • MessageManager
      • MessageUI
      • SendUI
    • 远程连接

案例概述

首先先说一下写的聊天室案例

使用MessageManager来作为RPC调用,提供全局添加Message方法的单例,其他类可以订阅对应的委托进行自己的处理,比如UI部分可以根据委托创建消息显示

NetworkManager是Unity提供的网络类,配合UnityTransport实现网络的传输和连接的管理

UI部分分三大部分:

  • 第一部分是输入消息内容并发送的部分
  • 第二部分是提供启动Host和Client的按钮部分
  • 第三部分就是消息的生成显示的部分。

关键代码部分

MessageManager

添加消息的RPC部分,该部分只负责转发委托,并不实际存储消息内容,由于一开始是希望方便测试查看网络相关的回调信息,所以添加了一个LogLevel控制消息的颜色,但后来又想不如加个聊天,再后来就成了个聊天室了()

    public void AddMessage(string name, string content, LogLevel level = LogLevel.Normal){AddMessageServerRPC(name, content, level);}[ServerRpc(RequireOwnership = false)]private void AddMessageServerRPC(string name, string content, LogLevel level = LogLevel.Normal){AddMessageClientRPC(name, content, level);}[ClientRpc]private void AddMessageClientRPC(string name, string content, LogLevel level = LogLevel.Normal){onMessageReceived.Invoke(name, content, level);}

接下来是在该类中重新在NetworkManager的StartHost和StartClient外面裹一层自己的代码

public void StartHost()
{//这一句后面详细解释NetworkManager.Singleton.GetComponent<UnityTransport>().SetConnectionData("你的公网IP", 7777, "0.0.0.0");//提示打印玩家的连接通知//Namer.GM是一个名称类,拿来代替直接使用"GM"的字符串方式,方便统一名称,统一修改,查找引用等NetworkManager.Singleton.OnClientConnectedCallback += (clientId) =>{Instance.AddMessage(Namer.GM, "player " + clientId + " Connected.", LogLevel.Warning);clientIDList.Add(clientId);};NetworkManager.Singleton.StartHost();
}public void StartClient()
{NetworkManager.Singleton.OnClientDisconnectCallback += (clientId) =>{onMessageReceived.Invoke(Namer.GM, "未能成功连接到服务器!", LogLevel.Error);};NetworkManager.Singleton.StartClient();
}

最后是该类中向外部提供的委托

public UnityAction<string, string, LogLevel> onMessageReceived;

MessageUI

接下来是消息的显示部分,这一部分订阅单例的消息委托并显示出来,注意textPrefab是一个网络物体,其父级要在初始化时就提供。并且要在NetworkManager的NetworkPrefabList中添加该Prefab

public class MessageUI : MonoBehaviour
{[SerializeField] private TextBlockUI textPrefab;[SerializeField] private Transform textParent;private void Start(){MessageManager.Instance.onMessageReceived += (name, content, level) =>{TextBlockUI obj = Instantiate(textPrefab, textParent);obj.SetText(name, content, level);};}
}

SendUI

这一部分算是负责发送消息的部分,本质上就是获取消息然后调用写好的函数就行,另外连接Host和Client只需要两个按钮分别调用MessageManager中对应的StartHost和StartClient就行,之后就不写了

public class SendUI : MonoBehaviour
{[SerializeField] private TMP_InputField inputField;[SerializeField] private TMP_Dropdown dropdown;[SerializeField] private Button submitBtn;[SerializeField] private TMP_InputField nameField;// Start is called before the first frame updatevoid Start(){submitBtn.onClick.AddListener(() =>{string name = nameField.text;string content = inputField.text;LogLevel level = (LogLevel)dropdown.value;MessageManager.Instance.AddMessage(name, content, level);inputField.text = "";});nameField.onEndEdit.AddListener((str) =>{PlayerPrefs.SetString("PlayerName", str);});}
}

上述写完后,在本地进行测试,没问题的话就可以准备进行远程连接了

远程连接

远程连接有许多方案,这里说一下我知道的

  1. Lobby + Relay : 在国内无服务器,连接靠玄学

  2. Unity Online Services:国内的网络服务,相关教程和API可在官网找到,可用,但是免费用户只有五十次房间额度,用完就无了

  3. 内网穿透:直接连接到玩家主机上,花费视使用的软件而定,最经济的办法是内网穿透做服务器然后放云上,或者像我一样直接用来Host连接,不额外搞服务器

内网穿透:

我使用的是路由侠,穿透时都会分配到一个公网的域名和对应端口,其映射到的内网端口通常选为127.0.0.1 : 7777,IP输入本机IP,后面的7777端口只要选一个没其他进程用的即可

确保穿透是打开的,域名对应的IP可以直接在CMD窗口中输入“ping 公网域名”,即可得到IP地址

公网的IP地址和端口填入Unity中NetworkManager下的UnityTransport的Address和Port中,并且打开运行远程连接

到达这一步会发现哪里都正常,但是客户端就是连不上服务器,最主要的一点是监听的端口问题

先打开服务器,再使用CMD,输入netstat -an | find "端口号"可以得到当前端口的状态,一般是

UDP 0.0.0.0:28907 *:*,这说明该端口当前监听所有UDP协议的IP地址连接,主机是正常监听的,

客户端也是连接的公网IP和端口,那么唯一的可能就是主机监听的端口和客户端不一致,客户端使用公网IP和端口进行连接,但最后端口会被映射到内网端口上,因此主机应当监听的是内网的对应端口,所以在StartHost时需要修改监听的端口值,也就是MessageManager中StartHost中的第一段代码

    NetworkManager.Singleton.GetComponent<UnityTransport>().SetConnectionData("你的公网IP", 7777, "0.0.0.0");

自此大功告成,能够通过内网穿透进行通信。

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

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

相关文章

机械行业数字化生产供应链产品解决方案(十二)

我们为机械行业提供的数字化生产供应链解决方案通过集成物联网、人工智能和大数据技术&#xff0c;打造了一套智能化的生产和供应链管理系统&#xff0c;实现了从设计、生产到物流的全程数字化、智能化。该系统通过实时数据采集与分析&#xff0c;优化生产计划和资源配置&#…

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第二篇:项目登录功能的实现

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

怎么等比例调整图片尺寸大小?调整图片尺寸的8个方法

在数字时代&#xff0c;图片已成为我们日常生活与工作中不可或缺的一部分。从社交媒体分享到专业设计项目&#xff0c;图片的质量和外观直接影响着信息的传达与接收。因此&#xff0c;在处理图片时&#xff0c;保持其原始的纵横比&#xff0c;即等比例调整图片尺寸&#xff0c;…

梅丽尔·斯特里普表演艺术家中心对外开放并恢复线下活动 体现了她的“卓越”

梅丽尔斯特里普表演艺术家中心对外开放并恢复线下活动 体现了她的“卓越” 2024-08-14 20:38 发布于&#xff1a;河北省 该中心将为美国演员工会和美国电视广播艺人协会的艺术家提供资源和机会&#xff0c;而且全部免费 同时命名的还有汤姆汉克斯和丽塔威尔逊放映室、妮可…

PHP 无参数RCE总结

在这篇文章中&#xff0c;我总结了在参与CTF比赛过程中积累的关于PHP无参数远程代码执行&#xff08;RCE&#xff09;的经验。由于一直以来时间有限&#xff0c;今天终于有机会整理这些知识点。 可能用到的函数&#xff08;PHP的内置函数&#xff09; localeconv() 函数返回一…

安美数字酒店宽带运营系统 weather.php 任意文件读取漏洞复现

0x01 产品简介 HiBOS酒店宽带运营系统是由安美世纪(北京)科技有限公司开发的一套专为酒店设计的宽带管理系统。该系统旨在提升酒店宽带服务的运营效率和安全性&#xff0c;为酒店客人提供稳定、高速、便捷的上网体验。 0x02 漏洞概述 安美数字酒店宽带运营系统 weather.php …

Ansible自动化运维中剧本角色(roles)来完成apache服务操作

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; Ansible…

Kafka服务端日志详解

文章目录 服务端日志Topic消息存储方式主体介绍log文件追加记录消息index和timeindex索引文件 日志文件清理Kafka的文件高效读写机制Kafka的文件结构顺序写磁盘零拷贝 合理配置刷盘频率客户端消费进度管理 服务端日志 Kafka的日志信息是通过conf/server.properties文件中的log…

互联网红利消退,AI 大模型接棒新红利

在科技发展的浪潮中&#xff0c;互联网曾经是推动经济增长和社会变革的强大引擎&#xff0c;为无数企业和个人带来了巨大的红利。然而&#xff0c;随着时间的推移&#xff0c;互联网红利似乎正在逐渐消退&#xff0c;而与此同时&#xff0c;AI 大模型正以其强大的创新能力和广泛…

搜索旋转排序数组

搜索旋转排序数组 没思路。 看了下全网的思路,一个个来o&#xff0c;多做点题就知道了二分不仅仅只能用在有序的数组中。 这道题很关键的一个值就是nums[0]。 法一&#xff1a;先用二分找到旋转点&#xff0c;旋转点两边都是的&#xff0c;判断要搜索的值在哪边&#xff0c;…

玩转haproxy --花十分钟看看,全是干货

Haproxy是一款开源集群软件&#xff08;在上一篇文章中提到过集群的相关知识&#xff0c;往期点击http://t.csdnimg.cn/qWtQG&#xff09;是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的&#xff0c;是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 …

Linux Day1 系统编程和文件操作

系统编程内容 文件I/O (输入/输出): 1&#xff09;使用标准库函数如fopen, fclose, fread, fwrite, fgetc, fputc, fgets, fprintf, fscanf等进行文件操作。 2&#xff09;使用open, close, read, write等系统调用来实现底层文件操作。 进程管理: 1&#xff09;使用fork, e…

安卓用户专属福利:OfficeSuite中文高级版,让你的工作更轻松!

OfficeSuite – 世界顶级移动办公软件&#xff01;Google Play商店下载最多的办公软件应用&#xff0c;迄今为止&#xff0c;智能手机平台上&#xff0c;功能最强大、兼容性最好的移动Office办公套件。创建&#xff0c;查看和编辑Word&#xff0c;Excel和PowerPoint文档&#x…

ThinkPHP5漏洞分析之代码执行

漏洞概要 本次漏洞存在于 ThinkPHP 的缓存类中。该类会将缓存数据通过序列化的方式&#xff0c;直接存储在 .php 文件中&#xff0c;攻击者通过精心构造的 payload &#xff0c;即可将 webshell 写入缓存文件。缓存文件的名字和目录均可预测出来&#xff0c;一旦缓存目录可访问…

python自动化笔记:os模块和异常处理

目录 一、os模块1.1、常用方法1.2、其他方法&#xff08;了解即可&#xff09; 二、异常处理 try except2.1、语法格式1&#xff1a;2.2、语法格式2&#xff1a;指定异常类别&#xff0c;捕获异常2.3、语法格式3&#xff1a;try-finally 语句无论是否发生异常都将执行最后的代码…

SQL每日一练-0814

今日SQL题难度&#xff1a;&#x1f31f;☆☆☆☆☆☆☆☆☆ 1、题目要求 找出每个部门中薪资最高的员工显示部门ID、部门名称、员工ID、员工姓名以及对应的薪资 2、表和虚拟数据 现有两个表&#xff1a;Employees 和 Departments&#xff0c;记录了员工和部门信息。…

【机器学习】ImageNet的基本概念以及如何使用ImageNet数据集

引言 ImageNet是一个大型的图像数据库&#xff0c;它根据WordNet的层级结构&#xff08;目前仅限于名词&#xff09;组织&#xff0c;其中每个层级节点都由成百上千张图像来描绘。这个项目对计算机视觉和深度学习研究的发展起到了重要作用 文章目录 引言一、ImageNet的基本概念…

一次sql请求,返回分页数据和总条数

日常搬砖&#xff0c;总少不了需要获取分页数据和总行数。 一直以来的实践是编码两次sql请求&#xff0c;分别拉分页数据和totalCount。 最近我在思考&#xff1a; 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多次更新&#xff0c;显而易见的优势&#xff1a; ① 能…

Halcon 算子汇总

gen_tuple_const(1000,1.5) 生成一个长度为1000&#xff0c;里面每一个数组元素都为1.5的数组 gen_tuple_const(100,chr(ord(a) 1)) 生成一个长度为100&#xff0c;里面每一个数组元素都为b的数组 ord函数是库函数&#xff0c;用于获取字符的ASCII值 chr(ord(a) 1) 结…

8.13-LVS的nat模式+DR模式

LVS 一、nat模式 1.角色 主机名ip地址功能web01192.168.2.101rsweb02192.168.2.102realserveenat内网:192.168.2.103 外网:192.168.2.120directorserver,ntpdns192.168.2.105dns 2..web服务器 [rootweb01 ~]# yum -y install nginx ​ [rootweb01 ~]# echo "web01&qu…