接下來 先講講服務(wù)端的吧
代碼部分解析
這里兩個類都要引用 KGSocket dll的
1.ChatNetData 建立一個 客戶端 服務(wù)端共用的數(shù)據(jù) 類庫 因為要互相傳的所以肯定要統(tǒng)一
目標(biāo)框架要選擇這個Unity 3.5 .net Subset Base Class Libraries導(dǎo)出的dll Unity 才能用
里面就是一些數(shù)據(jù)結(jié)構(gòu)了
網(wǎng)絡(luò)消息自定義類 要繼承KGNetData 打上Serializable 序列化標(biāo)簽
枚舉那些因為沒辦法序列化所以用Int的代替然后接收到再強轉(zhuǎn)回來
using KGSocket;
using System;
namespace ChatNetData
{
[Serializable]
public class ChatDatas:KGNetData
{
public byte[] HeadData;
public string PlayerName;
public SendChat Chatdata;
}
}
namespace ChatNetData
{
public enum CMD
{
None,
ReqLogin,
ReqChatInfo,
RspLogin,
RspChatInfo,
}
}
namespace ChatNetData
{
public enum ErrorInfo
{
None,
NameRepeatsErr,//名字重復(fù)登錄錯誤指令
}
}
using System;
namespace ChatNetData
{
[Serializable]
public class SendChat
{
public string chat;
public int Islocal;
}
}
2.ChatDatasPack 用于分辨數(shù)據(jù)是哪個客戶端發(fā)定的數(shù)據(jù)類型**
using ChatNetData;
namespace ChatServer
{
public class ChatDatasPack
{
public ChatSession chatSession;
public ChatDatas chatDatas;
}
}
using ChatNetData;
namespace ChatServer
{
public class ChatDatasPack
{
public ChatSession chatSession;
public ChatDatas chatDatas;
}
}
3.ChatSessio 每個客戶端的通信都是他來操作**
要繼承KGNetSession<ChatDatas> ChatDatas就是自己定義繼承KGNetData的數(shù)據(jù)類
這里主要的就是 OnDisRecive 斷開回調(diào) ,OnReciveData接收到數(shù)據(jù)回調(diào) OnStartRecive 連接成功回調(diào)
OnReciveData(ChatDatas data) 接收到數(shù)據(jù)會 new一個ChatDatasPack 賦值 添加到ChatServe的任務(wù)隊列 排序處理
using KGSocket;
using ChatNetData;
namespace ChatServer
{
public class ChatSession : KGNetSession<ChatDatas>
{
public int SessionID = 0;
public string PlayerName;//緩存用戶的名字public byte[] HeadData;//緩存用戶的頭像圖片數(shù)據(jù)
protected override void OnDisRecive()
{
("名字:" + PlayerName + "已下線").KLog();
}
protected override void OnReciveData(ChatDatas data)
{
("收到名字:" + data.PlayerName + "的請求"+(CMD)data.Cmd).KLog();
ChatServe.Instance.AddDataPackQue(this,data);
}
protected override void OnStartRecive()
{
SessionID = ChatServe.Instance.GetSessionID();
("ID:" + SessionID + "已連接").KLog();
}
}
}
4.ChatServe 這個就是創(chuàng)建服務(wù)器socket的了 緩存客戶端 處理接收各個客戶端信息返回的業(yè)務(wù)邏輯
要繼承KGSocketServe<ChatSession, ChatDatas>
這里AddDataPackQue 就是添加接收到的消息任務(wù)隊列的,會用到一個線程鎖堡称,
lock 這里簡單說一下 作用是被lock的對象撒会,里面的語句塊 一次只被一個線程使用 如果在使用中的 其他線程就會排隊等待執(zhí)行完再輪到下一個 不會出現(xiàn)一窩蜂調(diào)用 順序錯亂情況
添加完后 在Update() 這里進行出列調(diào)用 主線程那邊就可以直接一直調(diào)用Update一直刷新有沒有新的任務(wù)隊列就好
然后DisposePack這里就是處理從客戶端接收到的數(shù)據(jù)了 判斷指令調(diào)用對應(yīng)業(yè)務(wù)邏輯
using System.Linq;
using KGSocket;
using ChatNetData;
namespace ChatServer
{
public class ChatServe : KGSocketServe<ChatSession, ChatDatas>
{
private static ChatServe instance;
public static ChatServe Instance
{
get
{
if (instance == null)
{
instance = new ChatServe();
}
return instance;
}
set => instance = value;
}
public static readonly object obj = "lock";
public Queue<ChatDatasPack> DataPackQue = new Queue<ChatDatasPack>();
#region 緩存
private int SessionID = 0;
public int GetSessionID()
{
if (SessionID == int.MaxValue)
{
SessionID = 0;
}
return SessionID += 1;
}
public bool IsUserOnLine(string name)
{
return SessionList.Select(v=>v.PlayerName).ToList().Contains(name) ;
}
#endregion
public void Update()
{
if (DataPackQue.Count>0)
{
lock (obj)
{
DisposePack(DataPackQue.Dequeue());
}
}
}
public void DisposePack(ChatDatasPack pack)
{
switch ((CMD)pack.chatDatas.Cmd)
{
case CMD.ReqLogin:
//判斷在線的名字是否重復(fù)
if (IsUserOnLine(pack.chatDatas.PlayerName))
{
pack.chatDatas.Err = (int)ErrorInfo.NameRepeatsErr;
}
else
{
pack.chatSession.PlayerName = pack.chatDatas.PlayerName;
pack.chatSession.HeadData = pack.chatDatas.HeadData;
pack.chatDatas.Cmd = (int)CMD.RspLogin;
}
pack.chatSession.SendData(pack.chatDatas);
break;
case CMD.ReqChatInfo:
pack.chatDatas.Cmd = (int)CMD.RspChatInfo;
pack.chatDatas.HeadData = pack.chatSession.HeadData;
pack.chatDatas.PlayerName = pack.chatSession.PlayerName;
//發(fā)回給自身聊天
pack.chatSession.SendData(pack.chatDatas);
//改成對方
pack.chatDatas.Chatdata.Islocal = 1;
//分發(fā)到各個客戶端 聊天消息
SessionList.Where(v=>v!=pack.chatSession).ToList().ForEach(v=>
{
v.SendData(pack.chatDatas);
});
break;
}
}
public void AddDataPackQue(ChatSession session, ChatDatas chatData)
{
lock (obj)
{
DataPackQue.Enqueue(new ChatDatasPack { chatSession = session, chatDatas = chatData });
}
}
}
}
https://github.com/LKaiGuo/KGScriptGenerator 喜歡的給我點個星星啊
u3d萌新QQ群844087555 歡迎進來灌水=器躏。=