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

news2024/11/13 9:17:10

这两天在做那个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 update
    void 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.coloradmin.cn/o/2038476.html

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

相关文章

图论------Bellman-Ford算法求单源最短路径的优化

目录 前情回顾&#xff1a; 画图分析&#xff1a; 具体代码&#xff1a; 前情回顾&#xff1a; 大家是否还记得我们之前讲过的Bellman-Ford算法&#xff0c;如果忘记的话可以点击链接去复习一下&#xff1a;图论------贝尔曼-福德&#xff08;Bellman-Ford&#xff09;算法-…

C# NX二次开发-曲线延长和缩短

图示&#xff1a;延长曲线 代码&#xff1a;正值延长负值缩短 var cl workPart.Features.CreateCurvelengthBuilder(null);cl.CurvelengthData.ExtensionMethod NXOpen.GeometricUtilities.ExtensionMethod.Incremental;cl.CurvelengthData.ExtensionSide NXOpen.GeometricU…

C++ 内存布局 - Part1: typeid, typeinfo及单继承

1. typeinfo定义 typeinfo中存储的是关于类型的信息&#xff0c;可以通过typeid操作符获取&#xff0c;对于没有虚函数的场景&#xff0c;typeid返回的是编译器静态类型信息&#xff0c;对于一个基类类型指针&#xff0c;哪怕其真实指向是个派生类&#xff0c;如果没有虚函数&…

求解答matlab,具体问题如下:

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

数据埋点系列 6|数据驱动决策的实际应用:从理论到实践

在前面的系列文章中&#xff0c;我们深入探讨了数据驱动决策的各个方面。现在&#xff0c;是时候将这些知识付诸实践了。本文将通过一个虚构但贴近现实的案例&#xff0c;展示如何在一个组织中实施数据驱动决策&#xff0c;同时我们将讨论在这个过程中可能遇到的挑战和解决方案…

HAProxy 全解析:驾驭网络负载均衡与高可用的强大引擎

一、什么是HAproxy HAProxy是一个免费、开源的高性能TCP/HTTP负载均衡器和代理服务器软件&#xff0c;主要用于实现以下功能 一、负载均衡 多种负载均衡算法支持&#xff1a; 轮询&#xff08;Round Robin&#xff09;&#xff1a;它依次将请求均匀分配到后端的各个服务器。例…

Linux进程--进程的调度和切换

文章目录 一、进程优先级1.优先级的概念2.优先级的实现 二、进程的调度和切换1.Linux的进程调度概念2.进程的切换1.硬件上下文2.Linux调度实现 一、进程优先级 1.优先级的概念 进程要访问某种资源&#xff0c;要进行进程上的排队&#xff0c;来确认享受资源的前后顺序。 在x…

基于phpstudy对cmseasy5.5进行漏洞复现

目录&#xff1a; 漏洞复现的cmseasy5.5百度网盘链接 安装cmseasy&#xff1a; 1.在phpstudy上安装cmseasy 2.设置mysql密码为phpstudy内置mysql的密码并检查安装环境 3.安装后查看mysql内cmseasy是否有内容 获取用户名和密码过程&#xff1a; 1.查看源码发现有个remotelo…

字符串 - 反转字符串 II

541. 反转字符串 II 方法一&#xff1a;模拟&#xff08;reverse方法分开写&#xff09; /*** param {string} s* param {number} k* return {string}*/ var reverseStr function(s, k) {const n s.length;const arr Array.from(s);for (let i 0; i < n; i 2 * k) {re…

uniCloud服务空间选择支付宝云后,使用uni-file-picker扩展组件不回显的bug处理

问题概述 开发uniappunicloud项目&#xff0c;DCloud官方给出了很多好用的扩展组件&#xff0c;其中uni-file-picker图片上传组件非常好用&#xff0c;不用编写代码&#xff0c;即可将本地图片上传到云存储中。 原来云开发一直选择的是阿里云服务空间&#xff0c;官方一直推支…

汇编:基本指令及格式

汇编不区分大小写 寄存器只有名字&#xff0c;没有地址 Nop 栈先初始化 import引用外部函数 export外部可用声明 函数传参&#xff08;默认先使用寄存器R0~R3&#xff09;: 1.四个以内的参数使用 R0~R3 2.超过四个的参数使用栈传递 返回值: 返回值存放在R0中 立即数&…

还不会部署本地AI大模型?LangChat带你快速接入并部署本地大模型

LangChat是Java生态下企业级AIGC项目解决方案&#xff0c;在RBAC权限体系的基础上&#xff0c;集成AIGC大模型功能&#xff0c;帮助企业快速定制知识库、企业机器人。 产品官网&#xff1a;LangChat – LangChat LangChat源码&#xff1a;https://github.com/tycoding/langcha…

【机器学习】神经网络通过梯度下降学习的步骤以及前向传播的详细步骤

引言 神经网络中的梯度下降是一种优化算法&#xff0c;用于训练网络&#xff0c;即调整网络的权重和偏置&#xff0c;以最小化损失函数 文章目录 引言一、神经网络通过梯度下降学习的步骤1.1 初始化网络参数1.2 前向传播&#xff08;Forward Propagation&#xff09;1.3 计算损…

优化大量数据导出到Excel的内存消耗(二):如果数据超出Excel单表上限,则进行分表

优化前&#xff1a;优化大量数据导出到Excel的内存消耗_大文件异步导出 内存占用高-CSDN博客 写Excel文件报错&#xff1a;Invalid row number (1048576) outside allowable range (0..1048575) 写入Excel时遇到IllegalArgumentException&#xff0c;原因是超出允许的最大行数…

哪些岗位在拿着年薪百万?

​根据脉脉数据研究院 2020 年 8 月 2 日最新发布的《中国高端人才透视2020》(以下简称“报告”)&#xff0c;高端人才占比的最多的行业&#xff0c;其实不是互联网。 报告显示&#xff0c;以高薪金领人才相比于该行业的整体人才数量的占比来计算&#xff0c;排名前三的是金融、…

【分割大模型】SAM2(Segment Anything2)新的分割一切大模型(原理+安装+代码)

文章目录 前言1.特点2.结构3.应用场景 一、原理1.1 引言1.2 任务&#xff1a;可提示的视觉分割1.3 模型1.4 数据引擎 与 SA-V数据集 二、安装与使用 项目地址&#xff1a;https://github.com/facebookresearch/segment-anything-2 前言 Segment Anything Model 2&#xff08;S…

使用SSL认证访问操作手册

完整版 【金山文档 | WPS云文档】 使用SSL认证访问操作手册 https://kdocs.cn/l/cuxGfHD17eEw

vue2.0和vue3.0区别

vue2.0和vue3.0区别 双向数据绑定的原理改变&#xff1a;‌ Vue2使用Object.defineProperty对数据进行劫持&#xff0c;‌结合发布订阅模式实现双向数据绑定&#xff0c;‌而Vue3则采用了ES6的Proxy API对数据进行代理&#xff0c;‌提供了更多的拦截操作&#xff0c;‌能够监…

KBL406-ASEMI、AI智能专用整流桥KBL406

编辑&#xff1a;ll KBL406-ASEMI、AI智能专用整流桥KBL406 型号&#xff1a;KBL406 品牌&#xff1a;ASEMI 封装&#xff1a;KBL-4 批号&#xff1a;2024 现货&#xff1a;50000 正向电流&#xff08;Id&#xff09;&#xff1a;4A 反向耐压&#xff08;VRRM&#xff…

【智能流体力学】ANSYS Fluent流体仿真基础深度学习驱动的前期准备:CAX计算机辅助集成技术

目录 一、CAX计算机辅助集成技术二、计算机辅助工程(CAE)三、SCDM (Species Concentration Display Model) 显示和分析物质浓度分布的模型1. **SCDM概述**2. **主要功能**3. **功能特点**4. **使用步骤**5. **应用实例**6. **优点与限制**四、行业应用五、Fluent 软件功能1. …