Unity3d通过PhotonServer访问MySQL数据库
来源:互联网 发布:mac安装win7双系统 编辑:程序博客网 时间:2024/06/05 16:36
原文地址:blog.liujunliang.com.cn
接着上一篇文章内容继续开发
源码下载地址:点击打开链接
上一片篇文章介绍使用NHibernate完成类和数据库表的映射
本文将对NHibernate数据进行简单封装,方便在PhotonServer服务器中进行调用
using NHibernate;using NHibernate.Cfg;using MyGameServer.Domain;using NHibernate.Criterion;using System.Collections.Generic;namespace MyGameServer.Helper{ public static class NHibernateHelper { private static ISessionFactory sessionFactory = null; private static ISession session = null; public static ISession GetSession { get { if (sessionFactory == null) { Configuration cfg = new Configuration(); //解析固定路径配置文件nhibernate.cfg.xml cfg.Configure(); //映射目标程序集 解析映射文件 Student.xml ...... cfg.AddAssembly(typeof(Student).Assembly); //获取会话对象 sessionFactory = cfg.BuildSessionFactory(); } session = sessionFactory.OpenSession(); return session; } private set { } } //添加行 public static void AddData<T>(T t) { using (ISession session = GetSession) { using (ITransaction transaction=session.BeginTransaction()) { GetSession.Save(t); transaction.Commit(); } } } //添加列 public static void RemoveData<T>(T t) { using (ISession session = GetSession) { using (ITransaction transaction = session.BeginTransaction()) { GetSession.Delete(t); transaction.Commit(); } } } //通过ID获取对象 public static T GetDataById<T>(int id) { using (ISession session = GetSession) { using (ITransaction transaction = session.BeginTransaction()) { T t = session.Get<T>(id); transaction.Commit(); return t; } } } /// <summary> /// 通过名称获取对象 /// </summary> /// <typeparam name="T">需要获取的对象</typeparam> /// <param name="dataBaseName">在数据库中的列名称</param> /// <param name="targetName">获取对象的目标名</param> /// <returns></returns> public static T GetDataByName<T>(string dataBaseName, string targetName) { using (ISession session = GetSession) { T t = session.CreateCriteria(typeof(T)).Add(Restrictions.Eq(dataBaseName, targetName)).UniqueResult<T>(); return t; } } /// <summary> /// 得到表内的全部对象 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static ICollection<T> GetAllUsers<T>() { using (ISession session = GetSession) { IList<T> ts = session.CreateCriteria(typeof(T)).List<T>(); return ts; } } //查询是否有符合id和姓名相同的对象 public static bool VerifyUser<T>(params object[] arg) { using (ISession session = GetSession) { T t = session .CreateCriteria(typeof(T)) .Add(Restrictions.Eq(arg[0].ToString(), arg[1]))//类属性名 属性值 .Add(Restrictions.Eq(arg[2].ToString(), arg[3])) .UniqueResult<T>(); if (t == null) { return false; } return true; } } /// <summary> /// 更新数据表 /// </summary> /// <typeparam name="T">数据表映射的对象</typeparam> /// <param name="t"></param> public static void UpdateData<T>(T t) { using (ISession session = GetSession) { using (ITransaction transaction=session.BeginTransaction()) { session.Update(t); transaction.Commit(); } } } }}
在主函数调用
using NHibernate;using NHibernate.Cfg;using LJL.Domain;using LJL.Helper;namespace LJL{ class Program { static void Main(string[] args) { Student sd = new Student { mID = 6, mName = "小张", mScore = 10 }; NHibernateHelper.AddData(sd); } }}
运行程序,一切正常,打开SQLyog,在student数据表中添加一行数据
接下来就是在PhotonServer中调用,来实现与MySQL数据库交互
按图下将类、配置文件集成到类库中(注意需要修改下类和配置文件中的程序集及命名空间)
接下来就是在Unity3d游戏客户端中与PhotonServer通信进而访问本地数据库
在Unity3d客户端上创建UI(这里简单拖入输入框和按钮)
如下图创建脚本
我们的游戏有很多中请求(比如登入、注册请求等等)
所以都继承自BaseRequest
using ExitGames.Client.Photon;using System.Collections;using System.Collections.Generic;using UnityEngine;public abstract class BaseRequest : MonoBehaviour{ [HideInInspector] //该请求的操作类型 public Collective.OperationMode operationMode = Collective.OperationMode.Default; public virtual void Start() { } public abstract void OnOperationRequest(); public abstract void OnOperationResponse(OperationResponse operationResponse);}
这里博主简单的做了一下登录请求
using ExitGames.Client.Photon;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class LoginRequest : BaseRequest{ //用户名 private InputField mInputName; //密码 private InputField mInputPassword; public override void Start() { operationMode = Collective.OperationMode.LOGIN; GameContext.GetInstance.AddRequest(this); mInputName = GameObject.Find("IDInputField").GetComponent<InputField>(); mInputPassword = GameObject.Find("NameInputField").GetComponent<InputField>(); //登录按钮点击事件 GameObject.Find("LoginButton").GetComponent<Button>().onClick.AddListener(() => { OnOperationRequest(); }); } public override void OnOperationRequest() { GameContext.GetInstance.peer.OpCustom( (byte)this.operationMode, new Dictionary<byte, object> { { (byte)Collective.ParameterMode.NAME, mInputName.text }, { (byte)Collective.ParameterMode.PASSWORD, mInputPassword.text } }, true ); } public override void OnOperationResponse(OperationResponse operationResponse) { Collective.OperationResult resultCode = (Collective.OperationResult)operationResponse.ReturnCode; if (resultCode == Collective.OperationResult.SUCCESS) { //登录成功 Debug.Log("用户登录成功"); } else if(resultCode == Collective.OperationResult.FAIL) { //登录失败 Debug.Log("登录失败"); } }}
最后附上上篇博文GameContext脚本,在这里有些地方发生了更新
using System.Linq;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using ExitGames.Client.Photon;public class GameContext : MonoBehaviour,IPhotonPeerListener{ /// <summary> /// 存储操作类型与请求 /// </summary> public Dictionary<Collective.OperationMode, BaseRequest> requestDic = new Dictionary<Collective.OperationMode, BaseRequest>(); public PhotonPeer peer; private static GameContext _instance; public static GameContext GetInstance { get { if (_instance == null) { _instance = GameObject.Find("GameContext").GetComponent<GameContext>(); } return _instance; } } public void DebugReturn(DebugLevel level, string message) { } //接收服务器发来的事件 public void OnEvent(EventData eventData) { switch (eventData.Code) { case 0: //获取事件数据 object value = eventData.Parameters.FirstOrDefault(q => q.Key == 1).Value; Debug.Log(value.ToString()); break; default: break; } } //接收响应数据(客户端发送了请求) public void OnOperationResponse(OperationResponse operationResponse) { BaseRequest request = requestDic.FirstOrDefault(q => q.Key == (Collective.OperationMode)operationResponse.OperationCode).Value; if (request != null) { request.OnOperationResponse(operationResponse); } else { //获取响应数据失败 Debug.LogError("获取响应数据失败"); } } //连接状态发送改变 public void OnStatusChanged(StatusCode statusCode) { Debug.Log("数据连接状态发生的改变:" + statusCode); } private void Start() { //传输协议UDP 、 通过Listener接收服务器端的响应 peer = new PhotonPeer(this, ConnectionProtocol.Udp); //连接本地服务器 peer.Connect("127.0.0.1:5055", "MYGameServer"); } private void Update() { //和服务器实时保持数据连接 peer.Service(); } private void OnDestroy() { if (peer != null && peer.PeerState == PeerStateValue.Connected) { //断开连接 peer.Disconnect(); } } public void AddRequest(BaseRequest request) { if (request != null) { requestDic.Add(request.operationMode, request); } else { Debug.LogError("添加数据为空"); } } public void RemoveRequest(BaseRequest request) { if (request != null && requestDic.ContainsValue(request)) { requestDic.Remove(request.operationMode); } else { Debug.LogError("移除失败"); } }}
其中Collective是生成的一个类库,该类库包含一些在客户端和服务器端都共同使用枚举类型(源码最后一起打包给大家学习)
在服务器端需要处理相似的逻辑
也是创建请求类,将各种请求继承自BaseRequest
在主类中对各中请求类加入到字典容器中,当监听到数据请求时候,寻找到相应的请求类进行对数据库数据操作(增、删、改、查)
并将最终数据返回给客户端(success、fail)
BaseRequest.cs
using Photon.SocketServer;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MyGameServer.Request{ public abstract class BaseRequest { public Collective.OperationMode operationMode = Collective.OperationMode.DEDAULF; public abstract void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer); }}
LoginRequest.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using MyGameServer.Request;using Photon.SocketServer;using MyGameServer.Helper;using MyGameServer.Domain;namespace MyGameServer.Request{ public class LoginRequest : BaseRequest { public LoginRequest() { operationMode = Collective.OperationMode.LOGIN; } public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer) { Dictionary<byte, object> parameterDic = operationRequest.Parameters; bool result = NHibernateHelper.VerifyUser<Student>( //类属性名、属性值 "mID", int.Parse(parameterDic.FirstOrDefault(q => q.Key == (byte)Collective.ParameterMode.NAME).Value.ToString()), "mName", parameterDic.FirstOrDefault(q => q.Key == (byte)Collective.ParameterMode.PASSWORD).Value.ToString() ); MyGameServer.LOG.Info(parameterDic.FirstOrDefault(q => q.Key == (byte)Collective.ParameterMode.NAME).Value.ToString()); MyGameServer.LOG.Info(parameterDic.FirstOrDefault(q => q.Key == (byte)Collective.ParameterMode.PASSWORD).Value.ToString()); OperationResponse response = new OperationResponse(operationRequest.OperationCode); response.ReturnCode = (short)Collective.OperationResult.FAIL; if (result) { response.ReturnCode = (short)Collective.OperationResult.SUCCESS; MyGameServer.LOG.Info("验证成功"); } peer.SendOperationResponse(response, sendParameters); } }}
其中附上上篇文章服务器端的MyGameServer.cs,在这里有所更新(添加字典容器用于将请求类存储)
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using System.IO;using ExitGames.Logging;using ExitGames.Logging.Log4Net;using log4net.Config;using MyGameServer.Domain;using MyGameServer.Helper;using MyGameServer.Request;namespace MyGameServer{ //服务器框架主类 框架入口 public class MyGameServer : Photon.SocketServer.ApplicationBase { public static Dictionary<byte, object> requestDic = new Dictionary<byte, object>(); //单例模式 public static ILogger LOG = LogManager.GetCurrentClassLogger(); //当有客户端接入时候调用 protected override PeerBase CreatePeer(InitRequest initRequest) { LOG.Info("有一个客户端连接进服务器"); AddRequestOperation(); return new ClientPeer(initRequest); } //当框架启动时候调用 protected override void Setup() { //设置配置文件属性 log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(Path.Combine(this.ApplicationRootPath, "bin_Win64"), "log");//设置日志文件存储目录 //日志配置文件 FileInfo logConfigFileInfo = new FileInfo(Path.Combine(this.BinaryPath, "log4net.config")); if (logConfigFileInfo.Exists)//配置文件存在 { //设置Photon日志插件为Log4Next LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance); //Log4Next这个插件读取配置文件 XmlConfigurator.ConfigureAndWatch(logConfigFileInfo); } LOG.Info("服务器初始化完成"); } //将含有的交互请求全部添加到字典里 private void AddRequestOperation() { requestDic.Clear(); BaseRequest request = new LoginRequest(); requestDic.Add((byte)request.operationMode, request); } //当框架停止时候调用 protected override void TearDown() { } }}
其中客户端类ClientPeer.cs数据监听函数需要修改
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Photon.SocketServer;using PhotonHostRuntimeInterfaces;using MyGameServer.Request;namespace MyGameServer{ public class ClientPeer : Photon.SocketServer.ClientPeer { public ClientPeer(InitRequest ir) : base(ir) { } //该客户端断开连接 protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail) { } //该客户端出操作请求 protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters) { BaseRequest request = (BaseRequest)MyGameServer.requestDic.FirstOrDefault(q => q.Key == (byte)operationRequest.OperationCode).Value; if (request != null) { request.OnOperationRequest(operationRequest, sendParameters, this); } else { MyGameServer.LOG.Info("获取请求操作失败"); } } }}
将解决方案重新生成一下,用PhotonControl开启MyGameServer
在Unity开启一个客户端
对数据进行验证,发现一切正常!!!
阅读全文
1 0
- Unity3d通过PhotonServer访问MySQL数据库
- 通过JDBC访问MySql数据库
- Unity3d客户端与PhotonServer通信
- Android通过PHP访问MySQL数据库
- Android数据库:通过JDBC直接访问MySql
- Java通过JDBC访问MySQL数据库实例
- java通过JDBC访问mysql数据库
- eclipse通过jdbc访问mysql数据库
- java之通过JDBC访问Mysql数据库
- 通过XAMPP访问phpmyadmin管理mysql数据库
- 如何通过ip访问MySql数据库
- Android客户端通过PHP访问MySQL数据库
- 6.通过JDBC访问MySql数据库
- jsp通过JDBC驱动访问mysql数据库
- 通过XAMPP访问phpmyadmin管理mysql数据库
- Unity3d访问数据库
- 通过MySQL提供的C API访问MySQL数据库
- 通过JDBC API 访问mysql数据库的servlet范例程序
- Maven 打包时加入本地依赖包
- Android BaseAdapter记录
- lucence in action读后感
- 分布式数据库中的CAP原理 CAP+BASE
- 如何使用gitee作为免费图床
- Unity3d通过PhotonServer访问MySQL数据库
- spring boot 通过Eureka搭建微服务
- Python+NLTK自然语言处理学习(一):环境搭建
- 卫星影像处理中间件开发报告
- spring注解形式设置定时器
- 容器的初级概念
- 自定义DialogFragment
- Java学习开始--第一天
- 第二章 SQL命令参考-DECLARE