Unity进阶--使用PhotonServer实现服务端和客户端通信--PhotonServer(一)

news2024/11/15 3:45:40

文章目录

  • Unity进阶--使用PhotonServer实现服务端和客户端通信
    • 服务器的安装和配置
    • 添加日志
    • 客户端的配置
    • 客户端和服务器的通信
    • Dlc 出现vscode引用不好使的时候

Unity进阶–使用PhotonServer实现服务端和客户端通信

服务器的安装和配置

Photon的地址:https://www.photonengine.com/zh-cn/sdks

  • 下载对应的sdk:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nqhFg3FR-1691110946416)(../AppData/Roaming/Typora/typora-user-images/image-20230802150527693.png)]

  • 在Visual studio 里创建新的类库:

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YNC7wHVC-1691110946416)(../AppData/Roaming/Typora/typora-user-images/image-20230802151715763.png)]**

在项目里添加对应的dll文件引用:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SfcLhTkB-1691110946417)(../AppData/Roaming/Typora/typora-user-images/image-20230802160144216.png)]

在这个文件夹里找:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v58YvXYT-1691110946417)(../AppData/Roaming/Typora/typora-user-images/image-20230802175928178.png)]

这五个插件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XdLbRv77-1691110946417)(../AppData/Roaming/Typora/typora-user-images/image-20230802160856827.png)]

编写服务器端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Photon.SocketServer;

namespace PhotonServerFirst
{
    public class PSTest : ApplicationBase
    {
        protected override PeerBase CreatePeer(InitRequest initRequest)
        { 
            return new PSpeer(initRequest);
        }

        protected override void Setup()
        {

        }

        protected override void TearDown()
        {

        }
    }
}

编写客户端模板

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;

namespace PhotonServerFirst
{
    public class PSpeer : ClientPeer
    {
        public PSpeer(InitRequest initRequest) : base(initRequest)
        {

        }

        protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
        {
            throw new NotImplementedException();
        }

        protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
        {
            throw new NotImplementedException();
        }
    }
}




    

创建服务器文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9g2BXhfS-1691110946417)(../AppData/Roaming/Typora/typora-user-images/image-20230802152237347.png)]

  • 修改生成目录:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZs48M4L-1691110946418)(../AppData/Roaming/Typora/typora-user-images/image-20230802182536425.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dvn72gRd-1691110946418)(../AppData/Roaming/Typora/typora-user-images/image-20230802182941475.png)]

放到之前创建的bin里。

然后生成。

  • 修改PhotonServer配置文件

在[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5BLT0QY-1691110946420)(../AppData/Roaming/Typora/typora-user-images/image-20230803090947410.png)]
寻找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PpBI5krl-1691110946424)(../AppData/Roaming/Typora/typora-user-images/image-20230803091005322.png)]

  • 配置文件:

         <!-- DisplayName:显示名称 -->
    	<PhotonServerFirst
    		MaxMessageSize="512000"
    		MaxQueuedDataPerPeer="512000"
    		PerPeerMaxReliableDataInTransit="51200"
    		PerPeerTransmitRateLimitKBSec="256"
    		PerPeerTransmitRatePeriodMilliseconds="200"
    		MinimumTimeout="5000"
    		MaximumTimeout="30000"
    		DisplayName="PhotonServerFirst"
    		>
    		
    		<!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
    		<!-- Port 5055 is Photon's default for UDP connections. -->
    		<UDPListeners>
    			<UDPListener
    				IPAddress="0.0.0.0"
    				Port="5055"
    				OverrideApplication="PhotonServerFirst">
    			</UDPListener>
    		</UDPListeners>
        
    		<!-- 0.0.0.0 opens listeners on all available IPs. Machines with multiple IPs should define the correct one here. -->
    		<!-- Port 4530 is Photon's default for TCP connecttions. -->
    		<!-- A Policy application is defined in case that policy requests are sent to this listener (known bug of some some flash clients) --> 
    		<TCPListeners>
    			<TCPListener
    				IPAddress="0.0.0.0"
    				Port="4530"
    				PolicyFile="Policy\assets\socket-policy.xml"
    				InactivityTimeout="10000"
    				OverrideApplication="PhotonServerFirst"				
    				>
    			</TCPListener>
    		</TCPListeners>
    
    
    		<!-- Defines the Photon Runtime Assembly to use. -->
    		<Runtime
    			Assembly="PhotonHostRuntime, Culture=neutral"
    			Type="PhotonHostRuntime.PhotonDomainManager"
    			UnhandledExceptionPolicy="Ignore">
    		</Runtime>
    				
    		<Applications Default="PhotonServerFirst">
    		
    			<!-- Name:要注意和上面填写的应用名字相同 -->
    			<!--BaseDirectory:编译好的dll所在文件夹名-->
    		    <!--Assembly:dll名-->
    		    <!--Type:命名空间.类名-->
    			<Application
    				Name="PhotonServerFirst"
    				BaseDirectory="PhotonServerFirst"
    				Assembly="PhotonServerFirst"
    				Type="PhotonServerFirst.PSTest"
    				ForceAutoRestart="true"
    				WatchFiles="dll;config"
    				ExcludeFiles="log4net.config">
    			</Application>
    
    		</Applications>
    	</PhotonServerFirst>
    

    这样photonServer下就有我们创建的服务器了。

添加日志

  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ocfdDxLc-1691110946425)(../AppData/Roaming/Typora/typora-user-images/image-20230803092647288.png)]
    下寻找log4net.config把它复制到工程里面。

  2. 然后把属性改为始终复制

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wJQkJxCi-1691110946427)(../AppData/Roaming/Typora/typora-user-images/image-20230803092916486.png)]

  3. 改一下输出的日志名字

    <file type="log4net.Util.PatternString" value="%property{Photon:ApplicationLogPath}\\PhotonServerFirst.Server.log" />
    
  4. 配置服务器程序

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Photon.SocketServer;
    using ExitGames.Logging;
    using ExitGames.Logging.Log4Net;
    using log4net.Config;
    using System.IO;
    
    namespace PhotonServerFirst
    {
        public class PSTest : ApplicationBase
        {
            //日志需要的
            private static readonly ILogger log = LogManager.GetCurrentClassLogger();
            protected override PeerBase CreatePeer(InitRequest initRequest)
            { 
                return new PSpeer(initRequest);
            }
    
            //初始化
            protected override void Setup()
            {
                InitLog();
                
            }
    
            //server端关闭的时候
            protected override void TearDown()
            {
    
            }
            #region 日志
            /// <summary>
            /// 初始化日志以及配置
            /// </summary>
            private void InitLog()
            {
                //日志的初始化
                log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = this.ApplicationRootPath + @"\bin_Win64\log";
                //设置日志的路径
                FileInfo configFileInfo = new FileInfo(this.BinaryPath + @"\log4net.config");
                //获取配置文件
                if (configFileInfo.Exists)
                {
                    //对photonserver设置日志为log4net
                    LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);
                    XmlConfigurator.ConfigureAndWatch(configFileInfo);
                    log.Info("初始化成功");
                }
            }
            #endregion        
            
        }
    }
    
    
  5. 打开photonserver运行应用,日志输出则配置成功。

客户端的配置

  1. Photon-OnPremise-Server-SDK_v4-0-29-11263 > lib >下寻找Photon3Unity3D.dll放到unity3d的插件文件夹(Pluigins)里。
  2. 编写客户端脚本绑定到一个单例不会被销毁的组件里。(代码如下)

客户端和服务器的通信

  • 客户端

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using ExitGames.Client.Photon;
    
    public class PhotonManager : MyrSingletonBase<PhotonManager>, IPhotonPeerListener
    {
        private PhotonPeer peer;
        void Awake() {
            DontDestroyOnLoad(this);
            
    
        }
        // Start is called before the first frame update
        void Start()
        {
            peer = new PhotonPeer(this, ConnectionProtocol.Tcp);
            peer.Connect("127.0.0.1:4530", "PhotonServerFirst");
        }
    
        void Update()
        {
            peer.Service();
            if (Input.GetKeyDown(KeyCode.Space))
            {
                Dictionary<byte, object> dic = new Dictionary<byte, object>();
                dic.Add(1,"你好,我是王小虎");
                peer.OpCustom(1, dic, true);
            }
        }
    
        private void OnDestroy() {
            //断开连接
            peer.Disconnect();    
        }
    
        public void DebugReturn(DebugLevel level, string message)
        {
    
        }
    
        /// <summary>
        /// 接收服务器事件
        /// </summary>
        /// <param name="eventData"></param>
        public void OnEvent(EventData eventData)
        {
            if(eventData.Code == 1) {
                Debug.Log("事件" + eventData.Parameters[1]);
            }
        }
    
        /// <summary>
        /// 接收服务器响应
        /// </summary>
        /// <param name="operationResponse"></param>
        public void OnOperationResponse(OperationResponse operationResponse)
        {
            if (operationResponse.OperationCode == 1){
                Debug.Log(operationResponse.Parameters[1]);
            }
    
        }
    
        /// <summary>
        /// 状态改变
        /// </summary>
        /// <param name="statusCode"></param>
        public void OnStatusChanged(StatusCode statusCode)
        {
            Debug.Log(statusCode);
        }
    
    }
    
    
  • 服务器

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Photon.SocketServer;
    using PhotonHostRuntimeInterfaces;
    
    namespace PhotonServerFirst
    {
        public class PSpeer : ClientPeer
        {
            public PSpeer(InitRequest initRequest) : base(initRequest)
            {
    
            }
    
            //处理客户端断开的后续工作
            protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
            {
                throw new NotImplementedException();
            }
    
            //处理客户端的请求
            protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
            {
                switch (operationRequest.OperationCode)
                {
                    case 1:
                        //收到
                        Dictionary<byte, object> data = operationRequest.Parameters;
                        PSTest.log.Info("收到客户端消息:" + data[1].ToString());
    
                        //返回
                        Dictionary<byte, object> data2 = new Dictionary<byte, object>();
                        data2.Add(1, "你好,我是服务器");
                        //  OperationResponse operationResponse = new OperationResponse();
                        //  operationResponse.OperationCode = 1;
                        //  operationResponse.Parameters = data2;
                        
                        //创建一个响应
                        OperationResponse operationResponse = new OperationResponse(1, data2);
                        SendOperationResponse(operationResponse, sendParameters);
    
                        //创建一个事件
                        EventData Edata = new EventData(1, data2); 
                        SendEvent(Edata, sendParameters);
    
                        break;
                    default:
                        break;
                }
            }
        }
    }
    
    

Dlc 出现vscode引用不好使的时候

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E1OopesN-1691110946427)(../AppData/Roaming/Typora/typora-user-images/image-20230803224102512.png)]

检查下这个。

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

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

相关文章

智能物流千人俱乐部---行业必备神器

千人俱乐部前两天正式推出了。 智能物流千人俱乐部详情 很多行业内的甲方和乙方的朋友过来问&#xff0c;这个千人俱乐部到底怎么玩&#xff1f;今天再来解释一下。 1、为什么搞这个千人俱乐部&#xff1f; 一个原因是&#xff1a;研习社天天都有甲方粉丝让推荐设备厂家&#x…

Wavefront .OBJ文件格式解读【3D】

OBJ&#xff08;或 .OBJ&#xff09;是一种几何定义文件格式&#xff0c;最初由 Wavefront Technologies 为其高级可视化器动画包开发。 该文件格式是开放的&#xff0c;已被其他 3D 图形应用程序供应商采用。 OBJ 文件格式是一种简单的数据格式&#xff0c;仅表示 3D 几何体&…

【力扣每日一题】2023.8.4 不同路径3

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 在二维网格之上&#xff0c;让我们模拟从开头走到末尾&#xff0c;并且要经过所有能经过的点&#xff0c;问我们有多少种走法。 看到这道…

【雕爷学编程】MicroPython动手做(31)——物联网之Easy IoT 3

1、物联网的诞生 美国计算机巨头微软(Microsoft)创办人、世界首富比尔盖茨&#xff0c;在1995年出版的《未来之路》一书中&#xff0c;提及“物物互联”。1998年麻省理工学院提出&#xff0c;当时被称作EPC系统的物联网构想。2005年11月&#xff0c;国际电信联盟发布《ITU互联网…

PCIE扩频时钟及参考时钟要求

Spread Spectrum Clocking 1. 概述 Spread Spectrum Clocking(扩频时钟)是采用一种可控的方式使系统时钟抖动以减少峰值能量的过程。主要是为了尽量减少电磁干扰(EMI),主要应用在PCle和USB应用中。与非调制时钟相比,扩频时钟具有相对较高的抖动,应确保下游元件能够承受扩频…

Python:Spider爬虫工程化入门到进阶(1)Scrapy

本文通过简单的小例子&#xff0c;亲自动手创建一个Spider爬虫工程化的Scrapy项目 本文默认读着已经掌握基本的Python编程知识 目录 1、环境准备1.1、创建虚拟环境1.2、安装Scrapy1.3、创建爬虫项目 2、爬虫示例-爬取壁纸2.1、分析目标网站2.2、生成爬虫文件2.3、编写爬虫代码…

用python做一个小项目,python做简单小项目

大家好&#xff0c;本文将围绕用python做一个小项目展开说明&#xff0c;python做简单小项目是一个很多人都想弄明白的事情&#xff0c;想搞清楚python入门小项目需要先了解以下几个事情。 来源丨网络 经常听到有朋友说&#xff0c;学习编程是一件非常枯燥无味的事情。其实&…

实现实时互动:用Spring Boot原生WebSocket打造你的专属聊天室

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; 实现实时互动&#xff1a;用Spring Boot原生WebSocket打造你的专属聊天…

详解Nodejs中的Process对象

在Nodejs中&#xff0c;process是一个全局对象&#xff0c;它提供了与当前进程和运行时环境交互的方法和属性。通过process对象&#xff0c;我们可以访问进程的信息、控制流程和进行进程间通信&#xff0c;这些都是服务端语言应该具备的能力。本文将全面介绍process对象的使用场…

【雕爷学编程】 MicroPython动手做(35)——体验小游戏2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

从感知到理解-融合语言模型的多模态大模型研究

©PaperWeekly 原创 作者 | 张燚钧 单位 | 中国移动云能力中心 研究方向 | 预训练大模型 引言 近年来&#xff0c;大语言模型&#xff08;Large language model, LLM&#xff09;取得了显著进展。以 ChatGPT 为代表的 LLM 在自然语言任务上展现出惊人的智能涌现能力。尽管…

TPU-NNTC 编译部署LPRNet 车牌识别算法

TPU-NNTC 编译部署LPRNet 车牌识别算法 注意&#xff1a; 由于SOPHGO SE5微服务器的CPU是基于ARM架构&#xff0c;以下步骤将在基于x86架构CPU的开发环境中完成 初始化开发环境(基于x86架构CPU的开发环境中完成)模型转换 (基于x86架构CPU的开发环境中完成) 处理后的LPRNet 项…

sql入门4--函数

字符串函数 # -----字符串函数----- # concat(s1,s2,....)拼接 select concat(Hello ,Mysql); #str转换为小写 select lower(HELLO); # str转换为大写 select upper(mysql); # 向左侧添加 str 位数 要添加的元素 select lpad(1, 3 ,-); # 向右侧添加 str 位数 要添加的元…

【单调栈part01】| 739.每日温度、496.下一个更大元素

&#x1f388;LeetCode739. 每日温度 链接&#xff1a;739.每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不…

rv1109/1126 rknn 模型部署过程

rv1109/1126是瑞芯微出的嵌入式AI芯片&#xff0c;带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上&#xff0c;需要经过模型转换和量化&#xff0c;下面记录一下整个过程。 量化环境 模型量化需要安装rk的工具包&#xff1a; rockchip-linux/rk…

weblogic XML反序列化分析——CVE-2017-10271

环境 https://vulhub.org/#/environments/weblogic/CVE-2017-10271/ 启动环境 docker-compose up -d代码审计 传入参数 中间跟进函数 最后的出口 没有限制&#xff0c;直接包参数传入xmlDecoder public String readLine() throws IOException {return (String)this.xml…

Class Central-全球在线课程搜索引擎和学习平台

Class Central&#xff08;课程中央网站&#xff09;是一个全球在线课程搜索引擎和学习平台&#xff0c;全球知名的慕课资源导航社区&#xff0c;汇集了来自Coursera&#xff08;斯坦佛大学&#xff09;、edX&#xff08;麻省理工学院&#xff09;、Futurelearn&#xff08;英国…

如何使用vue ui创建一个项目?

首先打开cmd 输入vue ui 等待浏览器打开一个窗口&#xff0c;按照下图操作 在"功能页面"中&#xff0c;各个插件代表以下意思&#xff1a; Babel&#xff1a;Babel是一个JavaScript编译器&#xff0c;用于将ES6代码转换为向后兼容的JavaScript版本&#xff0c;以确保…

ORB-SLAM2学习笔记6之D435i双目IR相机运行ROS版ORB-SLAM2并发布位姿pose的rostopic

文章目录 0 引言1 D435i相机配置2 新增发布双目位姿功能2.1 新增d435i_stereo.cc代码2.2 修改CMakeLists.txt2.3 新增配置文件D435i.yaml 3 编译运行和结果3.1 编译运行3.2 结果3.3 可能出现的问题 0 引言 ORB-SLAM2学习笔记1已成功编译安装ROS版本ORB-SLAM2到本地&#xff0c…

C++入门篇6 C++的内存管理

在学习C的内存管理之前&#xff0c;我们先来回顾一下C语言中动态内存 int main() {int* p1 (int*)malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别是什么&#xff1f;int* p2 (int*)calloc(4, sizeof(int));//calloc 可以初始化空间为0int* p3 (int*)reall…