首先我們?cè)趗nity客戶端里面先創(chuàng)建好我們的登陸UI界面嗎寂呛,一個(gè)是登陸界面LoginPanel,一個(gè)是注冊(cè)界面RegisterPanel伦籍,點(diǎn)擊注冊(cè)跳轉(zhuǎn)到注冊(cè)界面這么我就不說(shuō)了蓝晒,這里我只講解下實(shí)現(xiàn)點(diǎn)擊登陸發(fā)送請(qǐng)求給服務(wù)器然后服務(wù)器進(jìn)行驗(yàn)證并回應(yīng)給客戶端,實(shí)現(xiàn)點(diǎn)擊確認(rèn)注冊(cè)發(fā)送添加數(shù)據(jù)的請(qǐng)求并回應(yīng)給客戶端這兩個(gè)按鈕帖鸦。
下面開始做請(qǐng)求的發(fā)送了洛二。首先我們先大概的框架架構(gòu)好,先在unity客戶端里面創(chuàng)建一個(gè)總的請(qǐng)求類Request腳本攻锰,定義為抽象類繼承自MonoBehaviour晾嘶,然后再創(chuàng)建一個(gè)登陸請(qǐng)求的LoginRequest腳本和一個(gè)注冊(cè)請(qǐng)求的RegisterRequest腳本,讓這兩個(gè)請(qǐng)求都繼承自這個(gè)Request抽象類娶吞。然后讓這兩個(gè)請(qǐng)求腳本分別掛在載各自的登陸面板和注冊(cè)面板上垒迂。這時(shí)候請(qǐng)求的腳本創(chuàng)建好后就需要?jiǎng)?chuàng)建處理UI的腳本了。這時(shí)候再在各自的面板上創(chuàng)建處理UI的腳本妒蛇,我在LoginPanel面板上創(chuàng)建Loginpanel腳本在RegisterPanel面包上創(chuàng)建RegistrerPanel腳本這時(shí)候大概的一些腳本框架出來(lái)了
using UnityEngine;
using ExitGames.Client.Photon;
public abstract class Request:MonoBehaviour {
public abstract void DefaultRequse();//向服務(wù)器發(fā)起請(qǐng)求方法
public abstract void OnOperationResponse(OperationResponse operationResponse);//服務(wù)器收到消息響應(yīng)給客戶端的方法
}
然后去繼承這個(gè)抽象類的兩個(gè)腳本LoginRequest和RegisterRequest腳本里面實(shí)現(xiàn)著兩個(gè)方法,然后其實(shí)我們知道響應(yīng)的方法其實(shí)是在PhotonEngine腳本里面處理的,那么我們?cè)趺醋屵@個(gè)響應(yīng)調(diào)用到我們的Request方法里面呢,這時(shí)候我們就需要對(duì)這些Request做一些區(qū)分吏奸,那怎么去區(qū)分這些Request欢揖,我們每一個(gè)請(qǐng)求都對(duì)應(yīng)一個(gè)OperationCode,所以要給沒一個(gè)Request定義一個(gè)變量OperationCode苦丁,在我PhotonServer(二)的時(shí)候也提到了OperationCode表示發(fā)起請(qǐng)求的編號(hào)浸颓,接收的時(shí)候便于找到物臂,這個(gè)編號(hào)我看可以用去定義枚舉來(lái)實(shí)現(xiàn)旺拉。那么我們?cè)?strong>服務(wù)器端新建一個(gè)項(xiàng)目命名為Common,添加幾個(gè)類分別命名為ReturnCode、ParameterCode棵磷、OperationCode蛾狗、EventCode,寫入的枚舉分別為以下
namespace Common
{
public enum ReturnCode:short//區(qū)分請(qǐng)求返回值仪媒,成功或者失敗
{
Success,
Failed
}
}
namespace Common
{
public enum ParameterCode:byte//區(qū)分傳送數(shù)據(jù)時(shí)候參數(shù)的類型
{
Username,
Password
}
}
namespace Common
{
public enum OperationCode:byte//區(qū)分請(qǐng)求和響應(yīng)的類型
{
Login,
Register,
Default
}
}
namespace Common
{
public enum EventCode :byte//區(qū)分服務(wù)器向客戶端發(fā)送的事件的類型
{
//暫時(shí)不定義
}
}
然后再服務(wù)器MyGameServer里面添加引用選擇項(xiàng)目把我剛剛創(chuàng)建的Common項(xiàng)目添加進(jìn)來(lái)沉桌,然后把MyGameServer重新生成下。
然后可以在我們的文件夾里面找到Common.dll算吩,把這個(gè)dll導(dǎo)入到我們的unity的Plugins文件夾里面.
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
public abstract class Request:MonoBehaviour {
public OperationCode OpCode;
public abstract void DefaultRequse();//向服務(wù)器發(fā)起請(qǐng)求方法
public abstract void OnOperationResponse(OperationResponse operationResponse);//服務(wù)器收到消息響應(yīng)給客戶端的方法
然后就可以去指定相應(yīng)的OperationCode了
這時(shí)候我們就需要用代碼去關(guān)聯(lián)OnOperationResponse響應(yīng)到Request了。首先PhotonEngine里面的代碼
using System.Collections.Generic;
using UnityEngine;
using ExitGames.Client.Photon;
using Common;
public class PhotonEngine : MonoBehaviour,IPhotonPeerListener {
public static PhotonEngine Instance;
public static PhotonPeer Peer//讓外界可以訪問我們的PhotonPeer
{
get
{
return peer;
}
}
//創(chuàng)建一個(gè)字典偎巢,根據(jù)OperationCode去找到所有相對(duì)應(yīng)的Request對(duì)象
private Dictionary<OperationCode, Request> RequestDict = new Dictionary<OperationCode, Request>();
private static PhotonPeer peer;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this.gameObject);
}else if (Instance != this)
{
Destroy(this.gameObject);return;
}
}
// Use this for initialization
void Start () {
//連接服務(wù)器端
//通過Listender連接服務(wù)器端的響應(yīng)
//第一個(gè)參數(shù) 指定一個(gè)Licensed(監(jiān)聽器) ,第二個(gè)參數(shù)使用什么協(xié)議
peer = new PhotonPeer(this,ConnectionProtocol.Udp);
//連接 UDP的 Ip地址:端口號(hào)蔼夜,Application的名字
peer.Connect("127.0.0.1:5055", "MyGame1");
}
// Update is called once per frame
void Update () {
peer.Service();//需要一直調(diào)用Service方法,時(shí)時(shí)處理跟服務(wù)器端的連接
}
//當(dāng)游戲關(guān)閉的時(shí)候(停止運(yùn)行)調(diào)用OnDestroy
private void OnDestroy()
{
//如果peer不等于空并且狀態(tài)為正在連接
if (peer != null && peer.PeerState == PeerStateValue.Connected)
{
peer.Disconnect();//斷開連接
}
}
//
public void DebugReturn(DebugLevel level, string message)
{
}
//如果客戶端沒有發(fā)起請(qǐng)求,但是服務(wù)器端向客戶端通知一些事情的時(shí)候就會(huì)通過OnEvent來(lái)進(jìn)行響應(yīng)
public void OnEvent(EventData eventData)
{
}
//當(dāng)我們?cè)诳蛻舳讼蚍?wù)器端發(fā)起請(qǐng)求后压昼,服務(wù)器端接受處理這個(gè)請(qǐng)求給客戶端一個(gè)響應(yīng)就會(huì)在這個(gè)方法里進(jìn)行處理
public void OnOperationResponse(OperationResponse operationResponse)
{
OperationCode opCode = (OperationCode)operationResponse.OperationCode;//得到響應(yīng)的OperationCode
Request request = null;
bool temp = RequestDict.TryGetValue(opCode, out request);//是否得到這個(gè)響應(yīng)
// 如果得到這個(gè)響應(yīng)
if (temp)
{
request.OnOperationResponse(operationResponse);//處理Request里面的響應(yīng)
}
else
{
Debug.Log("沒有找到對(duì)應(yīng)的響應(yīng)處理對(duì)象");
}
}
//如果連接狀態(tài)發(fā)生改變的時(shí)候就會(huì)觸發(fā)這個(gè)方法求冷。
//連接狀態(tài)有五種,正在連接中(PeerStateValue.Connecting)窍霞,已經(jīng)連接上(PeerStateValue.Connected)匠题,正在斷開連接中( PeerStateValue.Disconnecting),已經(jīng)斷開連接(PeerStateValue.Disconnected)但金,正在進(jìn)行初始化(PeerStateValue.InitializingApplication)
public void OnStatusChanged(StatusCode statusCode) {
}
//添加Requst
public void AddRequst(Request requst)
{
RequestDict.Add(requst.OpCode, requst);
}
//移除Requst
public void RemoveRequst(Request request)
{
RequestDict.Remove(request.OpCode);
}
}
然后在Request腳本里面處理添加和移除Request.
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
public abstract class Request:MonoBehaviour {
public OperationCode OpCode;
public abstract void DefaultRequse();//向服務(wù)器發(fā)起請(qǐng)求方法
public abstract void OnOperationResponse(OperationResponse operationResponse);//服務(wù)器收到消息響應(yīng)給客戶端的方法
//當(dāng)這個(gè)組件初始化的時(shí)候添加這個(gè)Request
public virtual void Start()
{
PhotonEngine.Instance.AddRequst(this);
}
//當(dāng)這個(gè)組件被銷毀的時(shí)候移除這個(gè)Request
public void OnDestroy()
{
PhotonEngine.Instance.RemoveRequst(this);
}
}
處理客戶端向服務(wù)器端發(fā)起登陸請(qǐng)求并寫入接受服務(wù)器端響應(yīng)的方法
下面在LoginRequest腳本里的DefaultRequse方法里面開始寫入登陸請(qǐng)求的發(fā)起方法和響應(yīng)的方法了
using System.Collections.Generic;
using ExitGames.Client.Photon;
using UnityEngine;
using Common;
public class LoginRequest : Request
{
[HideInInspector]
public string Username;
[HideInInspector]
public string Password;
private Loginpanel loginpanel;
public override void Start()
{
base.Start();
loginpanel = GetComponent<Loginpanel>();
}
//發(fā)起請(qǐng)求
public override void DefaultRequse()
{
Dictionary<byte, object> data = new Dictionary<byte, object>();
data.Add((byte)ParameterCode.Username,Username);
data.Add((byte)ParameterCode.Password, Password);
PhotonEngine.Peer.OpCustom((byte)OpCode,data,true);//把用戶名和密碼傳遞給服務(wù)器
}
//得到響應(yīng)
public override void OnOperationResponse(OperationResponse operationResponse)
{
ReturnCode returnCode = (ReturnCode)operationResponse.ReturnCode;
loginpanel.OnLoginResponse(returnCode);
}
}
然后再Loginpanel腳本里面寫入處理面板UI操作的代碼,順便自行吧點(diǎn)擊登陸按鈕很點(diǎn)擊注冊(cè)按鈕的方法去注冊(cè)上吧韭山。
using UnityEngine;
using UnityEngine.UI;
using Common;
public class Loginpanel : MonoBehaviour {
public GameObject RegisterPanel;//注冊(cè)面板
public InputField username;//UI界面輸入的用戶名
public InputField password;//UI界面輸入的密碼
private LoginRequest loginRequest;//提示信息
public Text hintMessage;
private void Start()
{
loginRequest = GetComponent<LoginRequest>();
}
//點(diǎn)擊登陸按鈕
public void OnLoginButton()
{
hintMessage.text = "";
loginRequest.Username = username.text;
loginRequest.Password = password.text;
loginRequest.DefaultRequse();
}
//點(diǎn)擊注冊(cè)按鈕跳轉(zhuǎn)到注冊(cè)界面
public void OnRegisterButton()
{
gameObject.SetActive(false);
RegisterPanel.SetActive(true);
}
//登陸操作,如果驗(yàn)證成功登陸冷溃,失敗提示用戶或密碼錯(cuò)誤
public void OnLoginResponse(ReturnCode returnCode)
{
if (returnCode == ReturnCode.Success)
{
//驗(yàn)證成功掠哥,跳轉(zhuǎn)到下一個(gè)場(chǎng)景
hintMessage.text = "用戶名和密碼驗(yàn)證成功";
}
else if (returnCode == ReturnCode.Failed)
{
hintMessage.text = "用戶名或密碼錯(cuò)誤";
}
}
}
這時(shí)候我的客戶端的登陸請(qǐng)求已經(jīng)發(fā)送到了服務(wù)器端并且也寫入了接收服務(wù)器相應(yīng)請(qǐng)求的響應(yīng)的方法了
服務(wù)器端處理接收客戶端的登陸請(qǐng)求并返回響應(yīng)給客戶端
下面我們就要開始處理服務(wù)器端登陸的請(qǐng)求和響應(yīng)客戶端的方法了。
首先我們?cè)诜?wù)器MyGameServer上創(chuàng)建一個(gè)文件夾Hander,后續(xù)會(huì)把所有的請(qǐng)求處理器都放在這個(gè)文件夾里面秃诵,然后再Hander里面創(chuàng)建一個(gè)公共的抽象類BaseHandler來(lái)表示一些基礎(chǔ)的東西续搀,然后再在文件夾Hander下創(chuàng)建LoginHandler類(登陸的Hander)、RegisterHandler類(注冊(cè)的Hander)菠净、DefaultHandler類默認(rèn)的Hander
using Common;
using Photon.SocketServer;
namespace MyGameServer.Handler
{
public abstract class BaseHandler
{
public OperationCode opCode;
//處理請(qǐng)求的方法
public abstract void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer);
}
}
在這之后會(huì)有很多的hander對(duì)象比如請(qǐng)求登陸的hander請(qǐng)求注冊(cè)的hander等等禁舷,這時(shí)候我們需要用一個(gè)字典把這些hander管理起來(lái),在MyGameServer類的初始化方法Setup里面我們用字典把這些hander添加進(jìn)字典管理起來(lái)那就是在MyGameServer改成下面的代碼
using System.Collections.Generic;
using Photon.SocketServer;
using ExitGames.Logging;
using System.IO;
using ExitGames.Logging.Log4Net;
using log4net.Config;
using Common;
using MyGameServer.Handler;
namespace MyGameServer
{
//所有的Server端 主類都要繼承自applicationbase
public class MyGameServer : ApplicationBase
{
public static readonly ILogger log = LogManager.GetCurrentClassLogger();//定義一個(gè)Log對(duì)象
public static MyGameServer Instance { get; private set; }
//存儲(chǔ)所有的Handler
public Dictionary<OperationCode, BaseHandler> HandlerDict = new Dictionary<OperationCode, BaseHandler>();
//當(dāng)一個(gè)客戶端請(qǐng)求連接的時(shí)候彪杉,服務(wù)器端就會(huì)調(diào)用這個(gè)方法
//我們使用peerbase,表示和一個(gè)客戶端的鏈接,然后photon就會(huì)把這些鏈接管理起來(lái)
protected override PeerBase CreatePeer(InitRequest initRequest)
{
log.Info("一個(gè)客戶端連接進(jìn)來(lái)了!");
return new ClientPeer(initRequest);
}
//初始化(當(dāng)整個(gè)服務(wù)器啟動(dòng)起來(lái)的時(shí)候調(diào)用這個(gè)初始化)
protected override void Setup()
{
Instance = this;
//日志的初始化(定義配置文件log4net位置)
//Path.Combine 表示連接目錄和文件名牵咙,可以屏蔽平臺(tái)的差異
// Photon: ApplicationLogPath 就是配置文件里面路徑定義的屬性
//this.ApplicationPath 表示可以獲取photon的根目錄,就是Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy這個(gè)目錄
//這一步是設(shè)置日志輸出的文檔文件的位置派近,這里我們把文檔放在Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\bin_Win64\log里面
log4net.GlobalContext.Properties["Photon:ApplicationLogPath"] = Path.Combine(Path.Combine(Path.Combine(this.ApplicationRootPath,"bin_win64")),"log");
//this.BinaryPath表示可以獲取的部署目錄就是目錄Photon-OnPremise-Server-SDK_v4-0-29-11263\deploy\MyGameServer\bin
FileInfo configFileInfo = new FileInfo(Path.Combine(this.BinaryPath,"log4net.config"));//告訴log4net日志的配置文件的位置
//如果這個(gè)配置文件存在
if (configFileInfo.Exists)
{
LogManager.SetLoggerFactory(Log4NetLoggerFactory.Instance);//設(shè)置photon我們使用哪個(gè)日志插件
XmlConfigurator.ConfigureAndWatch(configFileInfo);//讓log4net這個(gè)插件讀取配置文件
}
log.Info("Setup Completed!");//最后利用log對(duì)象就可以輸出了
InitHandler();
}
//用來(lái)初始化Handler
public void InitHandler()
{
LoginHandler loginHandler = new LoginHandler();
HandlerDict.Add(loginHandler.opCode,loginHandler);
DefaultHandler defaultHandler = new DefaultHandler();
HandlerDict.Add(defaultHandler.opCode,defaultHandler);
RegisterHandler registerHandler = new RegisterHandler();
HandlerDict.Add(registerHandler.opCode, registerHandler);
}
//server端關(guān)閉的時(shí)候
protected override void TearDown()
{
log.Info("關(guān)閉了服務(wù)器");
}
}
}
這樣我們所有的hander都添加進(jìn)去管理了起來(lái)。因?yàn)槲颐看稳プ值浍@取值的時(shí)候都要用到TryGetValue的方式去回去比較麻煩所以下面我們給字典加一個(gè)擴(kuò)展方法洁桌,在Common這個(gè)項(xiàng)目里面添加一個(gè)文件夾工具Tools在這里面創(chuàng)建一個(gè)DictTool類渴丸,寫入下面的字典擴(kuò)展方法
using System.Collections.Generic;
namespace Common.Tools
{
public class DictTool
{
//擴(kuò)展方法
public static Value GetValue<Key, Value>(Dictionary<Key, Value> dicr, Key key)
{
Value value;
bool isSuccess = dicr.TryGetValue(key, out value);
if (isSuccess)
{
return value;
}
else
{
return default(Value);
}
}
}
}
這樣我們就可以直接獲取值了,然后在管理客戶端的類ClientPeer里面修改處理客戶端請(qǐng)求的方法OnOperationRequest();修改代碼如下
using Photon.SocketServer;
using PhotonHostRuntimeInterfaces;
using MyGameServer.Handler;
using Common.Tools;
using Common;
namespace MyGameServer
{
//管理跟客戶端的鏈接的
public class ClientPeer : Photon.SocketServer.ClientPeer
{
public ClientPeer(InitRequest initRequest) : base(initRequest)
{
}
//處理客戶端斷開連接的后續(xù)工作
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
}
//處理客戶端的請(qǐng)求
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
//OperationRequest封裝了請(qǐng)求的信息
//SendParameters 參數(shù),傳遞的數(shù)據(jù)
//通過客戶端的OperationCode從HandlerDict里面獲取到了需要的Hander
BaseHandler handler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict,(OperationCode)operationRequest.OperationCode);
//如果找到了需要的hander就調(diào)用我們hander里面處理請(qǐng)求的方法
if (handler != null)
{
handler.OnOperationRequest(operationRequest, sendParameters, this);
}
else//否則我們就使用默認(rèn)的hander
{
BaseHandler defaultHandler = DictTool.GetValue<OperationCode, BaseHandler>(MyGameServer.Instance.HandlerDict, OperationCode.Default);
defaultHandler.OnOperationRequest(operationRequest,sendParameters,this);
}
}
}
}
下面我們就開始處理LoginHandler類里面請(qǐng)求的代碼了
using Photon.SocketServer;
using Common;
using Common.Tools;
using MyGameServer.Manager;
namespace MyGameServer.Handler
{
//處理登陸請(qǐng)求的類
class LoginHandler : BaseHandler
{
public LoginHandler()
{
opCode=OperationCode.Login;//賦值OperationCode為L(zhǎng)ogin,表示處理的是那個(gè)請(qǐng)求
}
//登陸請(qǐng)求的處理的代碼
public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
{
//根據(jù)發(fā)送過來(lái)的請(qǐng)求獲得用戶名和密碼
string username = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Username)as string;
string password= DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Password) as string;
//連接數(shù)據(jù)庫(kù)進(jìn)行校驗(yàn)
UserManager manager = new UserManager();
bool isSuccess = manager.VerifyUser(username, password);
OperationResponse response = new OperationResponse(operationRequest.OperationCode);
//如果驗(yàn)證成功另凌,把成功的結(jié)果利用response.ReturnCode返回成功給客戶端
if (isSuccess)
{
response.ReturnCode = (short)Common.ReturnCode.Success;
}
else//否則返回失敗給客戶端
{
response.ReturnCode = (short)Common.ReturnCode.Failed;
}
//把上面的回應(yīng)給客戶端
peer.SendOperationResponse(response, sendParameters);
}
}
}
最后重新生成下MyGameServer,然后在吧Common.dll重新倒入到Unity3D中重啟服務(wù)器
這樣就完成了我們的客戶端發(fā)送請(qǐng)求給服務(wù)器谱轨,服務(wù)器連接數(shù)據(jù)庫(kù)驗(yàn)證用戶信息并把驗(yàn)證結(jié)果返回給客戶端。下面我們來(lái)驗(yàn)證下吠谢,先對(duì)比下數(shù)據(jù)庫(kù)
然后運(yùn)行Unity客戶端土童,先隨便輸一個(gè),驗(yàn)證失敗工坊,沒毛病献汗。
這樣我們的登陸請(qǐng)求就完成了,接下來(lái)開始處理注冊(cè)的請(qǐng)求王污,其實(shí)原理是一樣的罢吃,接下來(lái)我們來(lái) 看看如何操作。
注冊(cè)請(qǐng)求的發(fā)送
直接在RegisterRequest 腳本里面發(fā)起注冊(cè)請(qǐng)求昭齐,代碼如下
using System.Collections.Generic;
using ExitGames.Client.Photon;
using UnityEngine;
using Common;
public class RegisterRequest : Request
{
[HideInInspector]
public string username;
[HideInInspector]
public string password;
private RegistrerPanel registerPanel;
public override void Start()
{
base.Start();
registerPanel = GetComponent<RegistrerPanel>();
}
//發(fā)起請(qǐng)求
public override void DefaultRequse()
{
Dictionary<byte, object> data = new Dictionary<byte, object>();
data.Add((byte)ParameterCode.Username, username);
data.Add((byte)ParameterCode.Password, password);
PhotonEngine.Peer.OpCustom((byte)OpCode, data, true);
}
////得到服務(wù)器的響應(yīng)
public override void OnOperationResponse(OperationResponse operationResponse)
{
ReturnCode returnCode = (ReturnCode)operationResponse.ReturnCode;
registerPanel.OnRegisterResponse(returnCode);
}
}
然后在RegistrerPanel腳本里面處理按鈕的點(diǎn)擊事件和驗(yàn)證的方法
using UnityEngine;
using UnityEngine.UI;
using Common;
public class RegistrerPanel : MonoBehaviour {
public GameObject loginpanel;
public InputField usernameIF;
public InputField passwordIF;
public Text hintMassage;
private RegisterRequest registerRequest;
private void Start()
{
registerRequest = GetComponent<RegisterRequest>();
}
//點(diǎn)擊事件確認(rèn)登陸
public void OnRegisterButton()
{
hintMassage.text = "";
registerRequest.username = usernameIF.text;
registerRequest.password = passwordIF.text;
registerRequest.DefaultRequse();
}
//點(diǎn)擊事件返回
public void OnBackButton()
{
loginpanel.SetActive(true);
gameObject.SetActive(false);
}
public void OnRegisterResponse(ReturnCode returnCode)
{
if (returnCode == ReturnCode.Success)
{
hintMassage.text = "注冊(cè)成功尿招,請(qǐng)返回登陸";
}
else if (returnCode == ReturnCode.Failed)
{
hintMassage.text = "所用的用戶名已被注冊(cè),請(qǐng)更改用戶名";
}
}
}
這樣我們客戶端的請(qǐng)求和響應(yīng)就處理完畢了司浪,下面去服務(wù)器端處理請(qǐng)求的接收添加數(shù)據(jù)和對(duì)客戶端做出響應(yīng).
服務(wù)器端處理注冊(cè)請(qǐng)求的接收和響應(yīng)給客戶端
直接在RegisterHandler類里面處理注冊(cè)的請(qǐng)求
using Photon.SocketServer;
using Common;
using Common.Tools;
using MyGameServer.Manager;
using MyGameServer.Model;
namespace MyGameServer.Handler
{
//處理注冊(cè)請(qǐng)求的類
class RegisterHandler : BaseHandler
{
public RegisterHandler()
{
opCode = OperationCode.Register;
}
//注冊(cè)請(qǐng)求的處理的代碼
public override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters, ClientPeer peer)
{
string username = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Username) as string;
string password = DictTool.GetValue<byte, object>(operationRequest.Parameters, (byte)ParameterCode.Password) as string;
UserManager manager = new UserManager();
User user = manager.GetByUsername(username);//根據(jù)username查詢數(shù)據(jù)
OperationResponse responser = new OperationResponse(operationRequest.OperationCode);
//如果沒有查詢到代表這個(gè)用戶沒被注冊(cè)過可用
if (user == null)
{
//添加輸入的用戶和密碼進(jìn)數(shù)據(jù)庫(kù)
user = new User() { Username = username, Password = password };
manager.Add(user);
responser.ReturnCode = (short) ReturnCode.Success;//返回成功
}
else//否者這個(gè)用戶被注冊(cè)了
{
responser.ReturnCode = (short)ReturnCode.Failed;//返回失敗
}
// 把上面的結(jié)果給客戶端
peer.SendOperationResponse(responser,sendParameters);
}
}
}
這樣整個(gè)登陸和注冊(cè)的請(qǐng)求和回應(yīng)都完成了泊业,我們重新生成下重啟服務(wù)器測(cè)試下,啟動(dòng)Unity客戶端,隨便先注冊(cè)個(gè)用戶啊易,然后可以看到注冊(cè)成功了吁伺。
下面我們打開我們數(shù)據(jù)庫(kù)可以看到我們注冊(cè)的信息傳遞到了數(shù)據(jù)庫(kù)
這樣我們總共的登陸和注冊(cè)就完成了,有具體的細(xì)節(jié)和BUG大家可以自己去調(diào)試