宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述PhotonServer——实现客户端和服务器的通信(Unity实注册/登录)(上)相关的知识,希望能为你提供帮助。
上一节完成了服务器连接mysql数据,以及映射关系和部分框架实现,接下来我们实现客户端、服务器端信息通信,实现注册和登录功能。
1.创建登录注册界面
文章图片
2.UI搭建完成后,部署脚本
直接上代码: PhotonEngine
public class PhotonEngine : MonoBehaviour,IPhotonPeerListener
{
public static PhotonEngine Instance;
private static PhotonPeer peer;
public static PhotonPeer Peer//让外界可以访问我们的PhotonPeer
{
get {return peer;
}
}private Dictionary<
Common.CodeType, BaseHandler>
handleDict = new Dictionary<
Common.CodeType, BaseHandler>
();
private Dictionary<
Common.EventCode, BaseEvent>
eventDict = new Dictionary<
EventCode, BaseEvent>
();
private bool IsOnAnewConnect = false;
[Tooltip("ip:prot")]
public string Ip_port = "127.0.0.1:4530";
//58.216.47.58
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this.gameObject);
}
else if (Instance != this)
{
Destroy(this.gameObject);
return;
}
}private void Start()
{
//连接服务器端
//通过Listender连接服务器端的响应
//第一个参数 指定一个Licensed(监听器) ,第二个参数使用什么协议
peer = new PhotonPeer(this, ConnectionProtocol.Tcp);
StartUp();
}private void Update()
{
OnConnecting();
}private void OnApplicationQuit()
{
OnDestroyed();
}public void OnAnewConnect()
{
if (IsOnAnewConnect) StartUp();
}public void StartUp()
{
//连接 UDP的 Ip地址:端口号,Application的名字
peer.Connect(Ip_port, "AR_RemoteServer");
}public void OnConnecting()
{
peer.Service();
//需要一直调用Service方法,时时处理跟服务器端的连接
}public void OnDestroyed()
{
//如果peer不等于空并且状态为正在连接
if ( peer != null &
&
peer.PeerState == PeerStateValue.Connected)
{
peer.Disconnect();
//断开连接
}
}public void InitHandler()
{}public void DebugReturn(DebugLevel level, string message)
{}//如果客户端没有发起请求,但是服务器端向客户端通知一些事情的时候就会通过OnEvent来进行响应
public void OnEvent(EventData eventData)
{
BaseEvent onEvent = Tool.GetValue<
EventCode, BaseEvent>
(eventDict, (EventCode)eventData.Code);
if (onEvent != null) onEvent.OnEvent(eventData);
else Debug.Log("无此事件");
}//当我们在客户端向服务器端发起请求后,服务器端接受处理这个请求给客户端一个响应就会在这个方法里进行处理
public void OnOperationResponse(OperationResponse operationResponse)
{
BaseHandler handler = Tool.GetValue<
CodeType, BaseHandler>
(handleDict, (CodeType)operationResponse.OperationCode);
if (handler != null) handler.OnOperationResponse(operationResponse);
else Debug.Log("请求错误");
}//如果连接状态发生改变的时候就会触发这个方法。
//连接状态有五种,
//正在连接中(PeerStateValue.Connecting),
//已经连接上(PeerStateValue.Connected),
//正在断开连接中( PeerStateValue.Disconnecting),
//已经断开连接(PeerStateValue.Disconnected),
//正在进行初始化(PeerStateValue.InitializingApplication)
public void OnStatusChanged(StatusCode statusCode)
{
if (statusCode == StatusCode.DisconnectByServerTimeout
|| statusCode == StatusCode.ExceptionOnConnect
|| statusCode == StatusCode.DisconnectByServerLogic)
{
GameManager.Instance.OnCreatePeerTip(statusCode + " 服务器异常!");
IsOnAnewConnect = true;
}
else if(statusCode == StatusCode.Connect)
{
IsOnAnewConnect = false;
}
}public void AddHandler(BaseHandler baseHandler)
{
handleDict.Add(baseHandler.opCodeType, baseHandler);
}
public void RemoveHandler(BaseHandler baseHandler)
{
handleDict.Remove(baseHandler.opCodeType);
}
public void AddEvent(BaseEvent baseEvent)
{
eventDict.Add(baseEvent.eventCode, baseEvent);
}
public void RemoveEvent(BaseEvent baseEvent)
{
eventDict.Remove(baseEvent.eventCode);
}
}
Request
public class Request : Singleton<
Request>
{
private Dictionary<
byte, object>
data = https://www.songbingjia.com/android/new Dictionary<
byte, object>
();
/// <
summary>
/// 发送登录请求
/// <
/summary>
public void SendLoginRequest(string username, string password)
{
data.Clear();
data.Add((byte)ParameterCode.Username, username);
data.Add((byte)ParameterCode.Password, password);
PhotonEngine.Peer.SendOperation((byte)CodeType.LogIn, data, SendOptions.SendReliable);
}/// <
summary>
/// 发送注册请求
/// <
/summary>
public void SendRegisterRequest(string username, string password)
{
data.Clear();
data.Add((byte)ParameterCode.Username, username);
data.Add((byte)ParameterCode.Password, password);
PhotonEngine.Peer.SendOperation((byte)CodeType.Register, data, SendOptions.SendReliable);
}/// <
summary>
/// 注销请求
/// <
/summary>
/// <
param name="username">
<
/param>
/// <
param name="password">
<
/param>
public void SendRevampRequest(string username, string password)
{
data.Clear();
data.Add((byte)ParameterCode.Username, username);
data.Add((byte)ParameterCode.Password, password);
PhotonEngine.Peer.SendOperation((byte)CodeType.Revamp, data, SendOptions.SendReliable);
}/// <
summary>
/// 用户准备好告诉服务器
/// <
/summary>
/// <
param name="username">
<
/param>
public void SendSyncPlayerQuest(string username)
{
data.Clear();
data.Add((byte)ParameterCode.Username, username);
PhotonEngine.Peer.SendOperation((byte)CodeType.SyncPlayer, data, SendOptions.SendReliable);
}
}
BaseHandler
public abstract class BaseHandler : MonoBehaviour
{
public CodeType opCodeType;
/// <
summary>
/// 发送请求
/// <
/summary>
public abstract void DefaultRequest();
/// <
summary>
/// 接收客户端请求服务器返回的消息
/// <
/summary>
/// <
param name="response">
<
/param>
public abstract void OnOperationResponse(OperationResponse response);
public virtual void Start()
{
PhotonEngine.Instance.AddHandler(this);
}
public virtual void OnDestroy()
{
PhotonEngine.Instance.RemoveHandler(this);
}
}
BaseEvent
public abstract class BaseEvent : MonoBehaviour
{
public EventCode eventCode;
//接收服务器发送消息
public abstract void OnEvent(EventData eventData);
//接收服务器发来的消息
// Start is called before the first frame update
protected virtual void Start()
{
PhotonEngine.Instance.AddEvent(this);
}
protected virtual void OnDestroy()
{
PhotonEngine.Instance.RemoveEvent(this);
}
}
LoginPannel 登录
public class LoginPannel : MonoBehaviour
{
public Text logText;
public InputField username_inputField;
public InputField password_inputField;
public Button loginBtn;
private LoginHandler handler;
private void Awake()
{
handler = this.GetComponent<
LoginHandler>
();
}void Start()
{
loginBtn.onClick.AddListener(OnLoginClick);
}
//登录
void OnLoginClick()
{
logText.text = "";
handler.username = username_inputField.text;
handler.password = password_inputField.text;
handler.DefaultRequest();
}public void OnLoginedResponse(ReturnCode returnCode)
{
if (ReturnCode.Success == (ReturnCode)returnCode)
{
SceneManager.LoadSceneAsync(1);
}
else if (ReturnCode.Failed == (ReturnCode)returnCode)
{
logText.text = "登录失败,用户名或密码错误,请重新登录";
}
else if (ReturnCode.HaveLogined == (ReturnCode)returnCode)
{
logText.text = "登录失败,用户已经登录!";
}
}
}
RegisterPannel注册
public class RegisterPannel : MonoBehaviour
{
public Text logText;
public InputField username_inputField;
public InputField password_inputField;
public Button registerBtn;
private RegisterHandler handler;
private void Awake()
{
handler = this.GetComponent<
RegisterHandler>
();
}private void Start()
{
registerBtn.onClick.AddListener(OnRegisterClick);
}void OnRegisterClick()
{
logText.text = "";
handler.username = username_inputField.text;
handler.password = password_inputField.text;
handler.DefaultRequest();
}public void OnRegisterResponse(ReturnCode returnCode)
{
if(returnCode == ReturnCode.Success)
{
OnReturnClick();
}
else if(returnCode == ReturnCode.Failed)
{
logText.text = "用户名重复,请重新输入";
}
}
}
【PhotonServer——实现客户端和服务器的通信(Unity实注册/登录)(上)】这一节主要做客户端的代码实现,下节将服务器端的实现
推荐阅读
- Go区块链开发手把手教你导入Go语言第三方库
- 学会这5种JS函数继承方式,前端面试你至少成功50%
- Python中的函数参数(位置参数默认参数可变参数关键字参数和命名关键字参数)
- super-vlan 和 mux-vlan
- Netty-UDP与HTTPS协议
- Spark的两种核心Shuffle详解
- NAT原理总结iptables实现SNAT和DNAT。
- Java split函数的坑
- kafka 和zookeeper集群配置参考