流程

客户端

服务端

---------------------------------------------------------------------------------------------------------------------------------
客户端
PhotonEngine.cs:差不多算是主类吧,将其构造成单例,到时候方便调用
里面有处理服务端返回的响应的方法,还有接受客户端发来的事件的方法等等。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using ExitGames.Client.Photon;
- using Common;
- public class PhotonEngine : MonoBehaviour,IPhotonPeerListener {
- public static PhotonEngine Instance;
- //用字典来缓存每次的请求和码
- //这里就能体现出来我们Request抽象类的好处了,不然每次这边都是不同的类型,使用抽象类就统一了
- private Dictionary<OperationCode, Request> RequestDic = new Dictionary<OperationCode, Request>();
- public static PhotonPeer peer;
- private void Awake()
- {
- if (Instance == null)
- {
- Instance = this;
- //当前Gameobject不会随场景的销毁而销毁
- DontDestroyOnLoad(this.gameObject);
- }
- }
- void Start () {
- peer = new PhotonPeer(this,ConnectionProtocol.Udp);
- peer.Connect("127.0.0.1:5055", "MyGame6");//通过ip连接到到对应的我们config中配置的Allpication
- }
-
- void Update () {
- peer.Service();//开启服务
- }
- private void OnDestroy()//销毁的时候
- {
- if(peer!=null&&peer.PeerState == PeerStateValue.Connected)//如果存在且保持连接状态
- {
- peer.Disconnect();//就断开连接
- }
- }
- public void DebugReturn(DebugLevel level, string message)
- {
- }
- public void OnEvent(EventData eventData)
- {
- switch (eventData.Code)
- {
- case 1:
- //解析数据
- var data = eventData.Parameters;
- object intValue, StringValue;
- data.TryGetValue(1, out intValue);
- data.TryGetValue(2, out StringValue);
- Debug.Log("收到服务器的响应Event推送,OpCode:1" + intValue.ToString() + ":" + StringValue.ToString());
- break;
- default:
- break;
- }
- }
- public void OnOperationResponse(OperationResponse operationResponse)
- {
- Request request = null;
- //此处就是工具类
- DicTool.GetValue(RequestDic, (OperationCode)operationResponse.OperationCode)
- .OnOprationRespionse(operationResponse);
- //下面注释的代码可以用上方工具类代替
- //bool b =RequestDic.TryGetValue((OperationCode)operationResponse.OperationCode, out request);
- //if (b)
- //{
- // request.OnOprationRespionse(operationResponse);
- //}
- //else
- //{
- // Debug.LogError("未找到对应code的请求request");
- //}
- return;
- //switch (operationResponse.OperationCode)
- //{
- // case 1:
- // Debug.Log("收到服务器的响应,OpCode:1");
- // //解析数据
- // var data = operationResponse.Parameters;
- // object intValue;
- // data.TryGetValue(1, out intValue);
- // object StringValue;
- // data.TryGetValue(2, out StringValue);
- // Debug.Log("收到客户端的请求,OpCode:1" + intValue.ToString() + ":" + StringValue.ToString());
- // break;
- // default:
- // break;
- // }
- }
- public void OnStatusChanged(StatusCode statusCode)
- {
- Debug.LogError(statusCode);
- }
- //private Dictionary<OperationCode, Request> RequestDic = new Dictionary<OperationCode, Request>();
- public void AddRequest(Request r)
- {
- RequestDic.Add(r.OpCode, r);
- }
- public void RemoveRequest(Request r)
- {
- RequestDic.Remove(r.OpCode);
- }
- }
复制代码
Request.cs:抽象了,生命code和request以及对服务器返回的响应的响应response
- using Common;
- using ExitGames.Client.Photon;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public abstract class Request: MonoBehaviour
- {
- public OperationCode OpCode;
- //抽象方法就是只声明,具体的实现有子类完成
- public abstract void DefaultRequest();
- public abstract void OnOprationRespionse(OperationResponse operationResponse);
- public void Start()
- {
- PhotonEngine.Instance.AddRequest(this);
- }
- public void OnDestroy()
- {
- PhotonEngine.Instance.RemoveRequest(this);
- }
- }
复制代码
(登录)LoginRequest.cs:实现了抽象类中的方法
- using Common;
- using ExitGames.Client.Photon;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class LoginRequest : Request
- {
- //在unity面板隐藏
- [HideInInspector]
- public string UserName;
- [HideInInspector]
- public string Password;
- public override void DefaultRequest()
- {
- //构造参数
- var data = new Dictionary<byte, object>();
- //构造参数
- data.Add((byte)ParaCode.UserName,UserName);
- data.Add((byte)ParaCode.Password, Password);
- //发送
- PhotonEngine.peer.OpCustom((byte)OpCode, data, true);
- }
- public override void OnOprationRespionse(OperationResponse operationResponse)
- {
- Debug.Log(operationResponse.ReturnCode);
- }
- }
复制代码
(登录)LoginPanel.cs:用于获得输入的账号密码,以及点击的时候调用request
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class LoginPanel : MonoBehaviour {
- public GameObject SignPanel;
- void Start() {
- // SignPanel = GameObject.Find("SignInPanel");
- }
- void Update() {
- }
- public void OnLoginBtn()
- {
- print("OnLoginBtn()");
- var Request = GetComponent<LoginRequest>();
- Request.UserName = transform.Find("NameField").GetComponent<InputField>().text;
- Request.Password = transform.Find("PWField").GetComponent<InputField>().text;
- Request.DefaultRequest();
- }
- public void OnSign()
- {
- SignPanel.SetActive(true);
- gameObject.SetActive(false);
- }
- }
复制代码
(注册)LoginRequest.cs:实现抽象类中的方法
- using Common;
- using ExitGames.Client.Photon;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class LoginRequest : Request
- {
- //在unity面板隐藏
- [HideInInspector]
- public string UserName;
- [HideInInspector]
- public string Password;
- public override void DefaultRequest()
- {
- //构造参数
- var data = new Dictionary<byte, object>();
- //构造参数
- data.Add((byte)ParaCode.UserName,UserName);
- data.Add((byte)ParaCode.Password, Password);
- //发送
- PhotonEngine.peer.OpCustom((byte)OpCode, data, true);
- }
- public override void OnOprationRespionse(OperationResponse operationResponse)
- {
- Debug.Log(operationResponse.ReturnCode);
- }
- }
复制代码
(注册)LoginPanel.cs:用于获得输入的账号密码,以及点击的时候调用request
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class LoginPanel : MonoBehaviour {
- public GameObject SignPanel;
- void Start() {
- // SignPanel = GameObject.Find("SignInPanel");
- }
- void Update() {
- }
- public void OnLoginBtn()
- {
- print("OnLoginBtn()");
- var Request = GetComponent<LoginRequest>();
- Request.UserName = transform.Find("NameField").GetComponent<InputField>().text;
- Request.Password = transform.Find("PWField").GetComponent<InputField>().text;
- Request.DefaultRequest();
- }
- public void OnSign()
- {
- SignPanel.SetActive(true);
- gameObject.SetActive(false);
- }
- }
复制代码
---------------------------------------------------------------------------------------------------------------------------------
服务端
其中Nhibernate就不发了,之前的文章里发过了。(有用的)
然后这里面net连接mysql那个文件夹是之前测试用的,这里也不发了。(没用)
就发剩余的了(有用的)

Class1.cs:枚举,我认为这是协议
- namespace Common
- {
- public enum OperationCode : byte
- {
- Login,
- SignIn
- }
- public enum ParaCode : byte
- {
- UserName,
- Password
- }
- public enum ReturnCode : short
- {
- Success,
- Failed
- }
- }
复制代码
DicTools.cs:字典工具类,照着写,拿着用就完事了
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Common
- {
- public class DicTool
- {
- public static T2 GetValue<T1,T2>(Dictionary<T1,T2> dic, T1 key)
- {
- T2 value;
- bool isSuccess = dic.TryGetValue(key, out value);
- if (isSuccess)
- {
- return value;
- }
- else
- {
- return default(T2);
- }
- }
- }
- }
复制代码
BaseHandler.cs:和客户端的Request差不多,都是抽象类。定义code以及抽象方法
- using Common;
- using Photon.SocketServer;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace RRGameServer.Handler
- {
- public abstract class BaseHandler
- {
- public OperationCode OpCode;
- public abstract void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer);
- }
- }
复制代码
LoginHandler.cs:拿到登陆的请求,实现抽象类的方法,返回响应
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Common;
- using Photon.SocketServer;
- using RRGameServer.Manager;
- namespace RRGameServer.Handler
- {
- class LoginHandler : BaseHandler
- {
- public LoginHandler()
- {
- OpCode = Common.OperationCode.Login;
- }
- //服务端收到客户端的request,并且对其做出响应返回给客户端
- public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
- {
- string username = DicTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParaCode.UserName) as string;
- string password = DicTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParaCode.Password) as string;
- bool b= UserManager.Instance.VerifyUser(username, password);
- OperationResponse response = new OperationResponse(operationRequest.OperationCode);
- if (b)
- {
- response.ReturnCode = (short)Common.ReturnCode.Success;
- }
- else
- {
- response.ReturnCode = (short)Common.ReturnCode.Failed;
- }
- peer.SendOperationResponse(response, sendParameters);
- }
- }
- }
复制代码
SignHandler.cs:拿到注册的请求,实现抽象类的方法,返回响应
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Common;
- using Photon.SocketServer;
- using RRGameServer.Manager;
- using RRGameServer.Model;
- namespace RRGameServer.Handler
- {
- class SignHandler:BaseHandler
- {
- public SignHandler()
- {
- OpCode = Common.OperationCode.SignIn;
- }
- public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
- {
- string username = DicTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParaCode.UserName) as string;
- string password = DicTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParaCode.Password) as string;
- var user = UserManager.Instance.GetUserByName(username);
- OperationResponse response = new OperationResponse(operationRequest.OperationCode);
- if (user==null)
- {
- user = new User();
- user.Username = username;
- user.Password = password;
- UserManager.Instance.Add(user);
- response.ReturnCode = (short)Common.ReturnCode.Success;
- }
- else
- {
- response.ReturnCode = (short)Common.ReturnCode.Failed;
- }
- peer.SendOperationResponse(response, sendParameters);
- }
- }
- }
复制代码
UserManager.cs:可以对数据库进行操作,,增删改查以及比对校验啥的
复制代码
User.hbm.xml:配置表,配置与数据库交互
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
- assembly="RRGameServer"
- namespace="RRGameServer.Model">
- <!-- more mapping info here -->
- <class name="User" table="users">
- <id name="Id" column="id" type="Int32">
- <generator class="native"></generator>
- </id>
- <property name="Username" column="username" type="string"></property>
- <property name="Password" column="password" type="string"></property>
- <property name="Registerdate" column="registerdate" type="Date"></property>
- </class>
-
- </hibernate-mapping>
复制代码
users.cs:用户类,跟NHibernate一起用的
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace RRGameServer.Model
- {
- class User
- {
- public virtual int Id { get; set; }
- public virtual string Username { get; set; }
- public virtual string Password { get; set; }
- public virtual DateTime Registerdate { get; set; }
- }
- }
复制代码
ClientPeer.cs:处理客户端请求等功能
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Common;
- using Photon.SocketServer;
- using PhotonHostRuntimeInterfaces;
- using RRGameServer.Handler;
- namespace RRGameServer
- {
- public class ClientPeer : Photon.SocketServer.ClientPeer
- {
- public ClientPeer(InitRequest initRequest) : base(initRequest)
- {
- }
- //当每个客户端断开时
- protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
- {
-
- }
- //当客户端发起请求的时候
- protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
- {
- BaseHandler handler = DicTool.GetValue(MyGameServer.Instance.HandlerDic, (OperationCode)operationRequest.OperationCode);
- if (handler != null)
- {
- handler.OnOperationRequest(operationRequest, sendParameters,this);
- }
- else
- {
- MyGameServer.log.Info("找不到操作码:" + (OperationCode)operationRequest.OperationCode);
- }
- return;
- //switch (operationRequest.OperationCode)
- //{
- // case 1:
- // //解析数据
- // var data = operationRequest.Parameters;
- // object intValue;
- // data.TryGetValue(1, out intValue);
- // object StringValue;
- // data.TryGetValue(2, out StringValue);
- // //输出参数
- // MyGameServer.log.Info("收到客户端的请求,opcode:1"+intValue.ToString()+":"+StringValue.ToString());
- // //返回响应
- // OperationResponse opResponse = new OperationResponse(operationRequest.OperationCode);
- // //构造参数
- // var data2 = new Dictionary<byte, object>();
- // data2.Add(1, 100);
- // data2.Add(2, "这是服务端做的响应");
- // opResponse.SetParameters(data2);
- // //返回code,为发送过来的code,返回的参数,为发送过来的参数
- // SendOperationResponse(opResponse, sendParameters);
- // //推送一个Event
- // EventData ed = new EventData(1);
- // ed.Parameters = data2;
- // SendEvent(ed, new SendParameters());
- // break;
- // default:
- // break;
- //}
- }
- }
- }
复制代码
hibernate.cfg.xml:配置用户连接数据库啥的
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
- <session-factory>
- <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
- <property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>
- <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property>
- <property name="connection.connection_string">server=localhost;port=3306;database=gamedb;user=root;password=root</property>
- <property name="show_sql">true</property>
- </session-factory>
- </hibernate-configuration>
复制代码
MyGameServer.cs:主类,用于初始化字典,以及服务器的响应初始化,以及日志等操作。
(重要!)(●'◡'●)
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Common;
- using ExitGames.Logging;
- using ExitGames.Logging.Log4Net;
- using log4net.Config;
- using Photon.SocketServer;
- using RRGameServer.Handler;
- using RRGameServer.Manager;
- namespace RRGameServer
- {
- //所有的Server,都要继承ApplicationBase,然后实现ApplicationBase的三个方法
- public class MyGameServer : ApplicationBase
- {
- public static MyGameServer Instance;
- public static readonly ILogger log = LogManager.GetCurrentClassLogger();
- //当有一个客户端连接上以后,就会执行此方法
- protected override PeerBase CreatePeer(InitRequest initRequest)
- {
- log.Info("一个客户端连接");
- return new ClientPeer(initRequest);
- }
- //服务器初始化函数
- protected override void Setup()
- {
- Instance = this;
- log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(
- Path.Combine(this.ApplicationRootPath, "bin_Win64"), "log");
- FileInfo configFileInfo = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config"));
- if (configFileInfo.Exists)
- {
- LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//photon知道日志输出
- XmlConfigurator.ConfigureAndWatch(configFileInfo);//读取配置
- }
- log.Info("服务器启动啦");
- //log.Info(UserManager.Instance.GetUserById(7).Username);
- InitHandler();//初始化
- }
- //服务器关闭函数
- protected override void TearDown()
- {
- log.Info("服务器关闭啦");
- }
- public Dictionary<OperationCode, BaseHandler> HandlerDic = new Dictionary<OperationCode, BaseHandler>();
- public void InitHandler()
- {
- //一开始就全部初始化
- LoginHandler LH = new LoginHandler();
- //log.Info("初始化操作码:" + LH.OpCode);
- HandlerDic.Add(LH.OpCode, LH);
- SignHandler handler = new SignHandler();
- HandlerDic.Add(handler.OpCode, handler);
- }
- }
- }
复制代码
NHibernateHelper.cs:会话工厂,用于搞Nhibernate的那玩意,直接用就完事了。
- using NHibernate;
- using NHibernate.Cfg;
- using RRGameServer.Model;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace RRGameServer
- {
- class NHibernateHelper
- {
- private static ISessionFactory _sessionFactory;
- private static ISessionFactory sessionFactory
- {
- get
- {
- if (_sessionFactory == null)
- {
- var cfg = new Configuration();
- cfg.Configure();//解析配置文件
- cfg.AddAssembly("RRGameServer");
- _sessionFactory = cfg.BuildSessionFactory();
- }
- return _sessionFactory;
- }
- }
- public static ISession OpenSession()
- {
- return sessionFactory.OpenSession();
- }
- }
- }
复制代码
最后效果也懒得贴图了,就是unity的客户端和服务端以及数据库三者打通了。
客户端注册,服务端接受到注册,判断有没有,与数据库做对比,如果有的话,返回失败。如果没有,添加到数据库,返回给客户端成功。然后客户端在根据返回的码,做相应的操作。
客户端登陆,服务端接收到登录,判断账号密码和数据库里面是否相同,如果相同,返回成功,如果不同,返回失败。然后客户端在根据返回的码,做相应的操作。
基本上就三个函数,一个requst是客户端发送给服务端的请求。然后服务端会有一个response函数,用于接受客户端发过来的请求,并且你在处理这个请求的时候,还可以掉个api给客户端发回去你的处理结果。然后第三个函数是客户端用于接受服务端传回来的响应的函数,可以根据传回来的响应,做一些操作,比如弹出成功登录的页面啥的呀。
(●'◡'●)
( •̀ ω •́ )y
呜呜终于一个人配置、搭建、搞通了客户端和服务端还有数据库,搭建了架构QAQ
来源:https://blog.caogenba.net/Weirdo_ran/article/details/122413570
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |