概述
制作单线程
- 在所有涉及到数据库的操作,全部使用单线程
- 防止多个线程同时访问,从而造成数据错乱
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MyServer
{
public delegate void Executedelegate();
/// <summary>
/// 单线程类
/// </summary>
public class SingleExecute
{
private static object ob = new object();
private static SingleExecute instacne;
public static SingleExecute Instacne
{
get
{
lock (ob)
{
if (instacne == null)
{
instacne = new SingleExecute();
}
return instacne;
}
}
}
private object objLock = new object();
/// <summary>
/// 互斥锁
/// </summary>
private Mutex mutex;
public SingleExecute()
{
mutex = new Mutex();
}
/// <summary>
/// 单线程执行逻辑
/// </summary>
public void Execute(Executedelegate executedelegate)
{
lock (objLock)
{
mutex.WaitOne();
executedelegate();
mutex.ReleaseMutex();
}
}
}
}
数据库的操作
- 判断是否在线
- 判断用户名和密码是否一致
- 判断用户名是否为空
- 添加idClient字典,根据用户id查找client
数据库代码
using MyServer;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameServer.DadaBase
{
public class DatabaseManager
{
private static MySqlConnection sqlConnect;
/// <summary>
/// 根据ID保存Client的字典
/// </summary>
private static Dictionary<int, ClientPeer> idClientDic;
public static void StartConnect()
{
idClientDic = new Dictionary<int, ClientPeer>();
string conStr = "database=zjhgame;data source=127.0.0.1;port=3306;User=root;pwd=zhao19971225";
sqlConnect = new MySqlConnection(conStr);
sqlConnect.Open();//开启和数据库的连接
}
/// <summary>
/// 判断该用户名是否存在数据库中
/// </summary>
public static bool IsExistUserName(string userName)
{
//查询命令
MySqlCommand cmd = new MySqlCommand("select UserName from userinfo where UserName=@name", sqlConnect);
//设置参数,填入参数
cmd.Parameters.AddWithValue("name", userName);
//开始查询
MySqlDataReader reader = cmd.ExecuteReader();
//是否存在
bool result = reader.HasRows;
//关闭查询
reader.Close();
return result;
}
/// <summary>
/// 创建用户
/// </summary>
public static void CreatUser(string userName,string pwd)
{
//创建命令
MySqlCommand cmd = new MySqlCommand("insert into userinfo set UserName=@name,Password=@pwd,OnLine=0,IconName=@iconName",sqlConnect);
//对参数进行赋值
cmd.Parameters.AddWithValue("name",userName);
cmd.Parameters.AddWithValue("pwd",pwd);
Random random = new Random();
int index= random.Next(0,19);
cmd.Parameters.AddWithValue("iconName","headIcon_"+index.ToString());
cmd.ExecuteNonQuery();//只执行不查询
}
/// <summary>
/// 账号密码是否一致
/// </summary>
public static bool IsMatch(string userName,string pwd)
{
MySqlCommand cmd = new MySqlCommand("select * from userinfo where UserName=@name",sqlConnect);
cmd.Parameters.AddWithValue("name",userName);
//开始查询
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)//如果查询到了
{
reader.Read();//读取
//读取Password的内容和传入的密码相判断
bool result = reader.GetString("Password") == pwd;
reader.Close();
return result;
}
reader.Close();
return false;
}
/// <summary>
/// 是否在线
/// </summary>
public static bool IsOnline(string userName)
{
MySqlCommand cmd = new MySqlCommand("select OnLine from userinfo where UserName=@name",sqlConnect);
cmd.Parameters.AddWithValue("name",userName);
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
bool result = reader.GetBoolean("OnLine");
reader.Close();
return result;
}
reader.Close();
return false;
}
/// <summary>
/// 登陆上线
/// </summary>
public static void Login(string userName,ClientPeer client)
{
//更新在线状态
MySqlCommand cmd = new MySqlCommand("update userinfo set OnLine=true where UserName=@name",sqlConnect);
cmd.Parameters.AddWithValue("name",userName);
cmd.ExecuteNonQuery();
//获取ID和用户名
MySqlCommand cmd1 = new MySqlCommand("select * from userinfo where UserName=@name",sqlConnect);
cmd1.Parameters.AddWithValue("name",userName);
MySqlDataReader reader = cmd1.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
int Id = reader.GetInt32("ID");
client.id = Id;
client.userName = userName;
if (!idClientDic.ContainsKey(Id))
idClientDic.Add(Id,client);
reader.Close();
}
reader.Close();
}
/// <summary>
/// 根据UserID获得Client
/// </summary>
public static ClientPeer GetClientBuyUserId(int id)
{
if (idClientDic.ContainsKey(id))
{
return idClientDic[id];
}
return null;
}
}
}
接收客户端登陆请求的处理
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameServer.DadaBase;
using MyServer;
using Protocol.Code;
using Protocol.Dto;
namespace GameServer.Logic
{
/// <summary>
/// 账号模块的处理
/// </summary>
public class AccountHandler : IHandler
{
public void DisConnected(ClientPeer clientPeer)
{
}
public void Receive(ClientPeer client, int subCode, object value)
{
switch (subCode)
{
case AccountCode.Register_CREQ:
Register(client,value as AccountDto);
break;
case AccountCode.Login_CREQ:
Login(client,value as AccountDto);
break;
}
}
/// <summary>
/// 客户端请求登陆的处理
/// </summary>
private void Login(ClientPeer client, AccountDto dto)
{
SingleExecute.Instacne.Execute(()=>
{
if (DatabaseManager.IsExistUserName(dto.userName)==false)
{
//用户名不存在
client.SendMsg(OpCode.Account, AccountCode.LOgin_SRES, -1);
return;
}
if (DatabaseManager.IsMatch(dto.userName,dto.password)==false)
{
//账号密码不匹配
client.SendMsg(OpCode.Account, AccountCode.LOgin_SRES, -2);
return;
}
if (DatabaseManager.IsOnline(dto.userName))
{
//当前用户已在线
client.SendMsg(OpCode.Account, AccountCode.LOgin_SRES, -3);
return;
}
DatabaseManager.Login(dto.userName,client);
//登陆成功
client.SendMsg(OpCode.Account, AccountCode.LOgin_SRES, 0);
});
}
/// <summary>
///客户端注册请求的处理
/// </summary>
private void Register(ClientPeer client, AccountDto dto)
{
///单线程执行
///作用:防止多个线程同时访问,数据错乱
SingleExecute.Instacne.Execute(()=>
{
//判断数据库中是否存在该用户,存在就给客户端返回-1
if (DatabaseManager.IsExistUserName(dto.userName))
{
client.SendMsg(OpCode.Account, AccountCode.Register_SRES, -1);
return;
}
//判断数据库中是否存在该用户,不存在就创建该用户并给客户端返回0
DatabaseManager.CreatUser(dto.userName, dto.password);
client.SendMsg(OpCode.Account, AccountCode.Register_SRES, 0);
});
}
}
}
客户端处理服务器登陆请求后的回应
using Protocol.Code;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AccountHandler : BaseHandler
{
public override void OnReceive(int subCode, object value)
{
switch (subCode)
{
case AccountCode.Register_SRES:
Register_SRES((int)value);
break;
case AccountCode.LOgin_SRES:
Login_SRES((int)value);
break;
}
}
/// <summary>
/// 处理服务器端注册后的回应
/// </summary>
private void Register_SRES(int value)
{
if (value==-1)
{
EventCenter.Broadcast(EventDefine.Hint,"该用户已经被注册");
return;
}
if (value==0)
{
EventCenter.Broadcast(EventDefine.Hint, "注册成功");
}
}
/// <summary>
/// 处理服务器端登陆后的回应
/// </summary>
private void Login_SRES(int value)
{
Debug.Log(value);
switch (value)
{
case -3:
EventCenter.Broadcast(EventDefine.Hint, "当前用户已在线");
break;
case -2:
EventCenter.Broadcast(EventDefine.Hint, "账号密码不匹配");
break;
case -1:
EventCenter.Broadcast(EventDefine.Hint, "用户名不存在");
break;
case 0:
EventCenter.Broadcast(EventDefine.Hint, "登陆成功");
break;
}
}
}
有需要学习视频的欢迎关注微信公众号:
最后
以上就是虚幻犀牛为你收集整理的Zjh游戏(十二)登陆功能的实现的全部内容,希望文章能够帮你解决Zjh游戏(十二)登陆功能的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复