栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Unity注册登录Demo的实现-03(全部完整代码)(客户端、服务端、数据库)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Unity注册登录Demo的实现-03(全部完整代码)(客户端、服务端、数据库)

流程

客户端

服务端

---------------------------------------------------------------------------------------------------------------------------------

客户端

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 RequestDic = new Dictionary();

    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 RequestDic = new Dictionary();

    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();
        //构造参数
        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();
        Request.UserName = transform.Find("NameField").GetComponent().text;
        Request.Password = transform.Find("PWField").GetComponent().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();
        //构造参数
        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();
        Request.UserName = transform.Find("NameField").GetComponent().text;
        Request.Password = transform.Find("PWField").GetComponent().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(Dictionary 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(operationRequest.Parameters, (byte)ParaCode.UserName) as string;
            string password = DicTool.GetValue(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(operationRequest.Parameters, (byte)ParaCode.UserName) as string;
            string password = DicTool.GetValue(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:可以对数据库进行操作,,增删改查以及比对校验啥的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Criterion;
using RRGameServer.Model;

namespace RRGameServer.Manager
{
    class UserManager
    {
        public static UserManager Instance = new UserManager();
        public void Add(User user)
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session= NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(user);
                    transaction.Commit();
                }
            }
        }

        public void Update(User user)
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(user);
                    transaction.Commit();
                }
            }
        }

        //做用户名和密码的校验
        internal bool VerifyUser(string username, string password)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                User user= session
                    .CreateCriteria(typeof(User))
                    .Add(Restrictions.Eq("Username", username))
                    .Add(Restrictions.Eq("Password", password))
                    .UniqueResult();
                if (user == null)
                    return false;
                return true;
            }
        }

        public void Remove(User user)
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(user);
                    transaction.Commit();
                }
            }
        }

        public User GetUserById(int id)
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    var u = session.Get(id);
                    transaction.Commit();
                    return u;
                }
            }
        }

        public User GetUserByName(string name)
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session = NHibernateHelper.OpenSession())
            {
                return session.CreateCriteria(typeof(User)).Add(Restrictions.Eq("Username", name)).UniqueResult();
            }
        }

        public IList GetAll()
        {
            //using大括号之间的代码执行完毕之后,()里面的内存就会被回收
            using (ISession session = NHibernateHelper.OpenSession())
            {
                return session.CreateCriteria(typeof(User)).List();
            }
        }

    }
}

User.hbm.xml:配置表,配置与数据库交互




  

  
    
      
    
    
    
    
  
  

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();
            //        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:配置用户连接数据库啥的



  
    NHibernate.Connection.DriverConnectionProvider
    NHibernate.Dialect.MsSqlCeDialect
    NHibernate.Driver.MySqlDataDriver
    server=localhost;port=3306;database=gamedb;user=root;password=root

    true
  

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 HandlerDic = new Dictionary();

        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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/703833.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号