马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册帐号
x
这里 接着上次那个聊天室 说下改动吧 也没改多少就是客户端会发心跳包过来 服务器刷新超时时间并且回应 给客户端,如果都超时没有接到回应给 就会主动回调 超时事件 这就是心跳包的过程 服务端ChatServer全部代
[C#] 纯文本查看 复制代码 using System;
using System.Collections.Generic;
using System.Linq;
using KGSocket;
using ChatNetData;
using KGSocket.Tool;
namespace ChatServer
{
//各个客户端管理 业务逻辑都在这了
public class ChatServe : KGSocketServe<ChatSession, ChatDatas>
{
#region 这里是单例
private static ChatServe instance;
public static ChatServe Instance
{
get
{
if (instance == null)
{
instance = new ChatServe();
}
return instance;
}
set => instance = value;
}
#endregion
public static readonly string 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 KGHeartBeatManage<ChatSession, KGHeartBeat> kGHeartBeatManage;
public void Update()
{
if (DataPackQue.Count > 0)
{
//多线程调用就要加个线程锁了避免同时调用
lock (obj)
{
DisposePack(DataPackQue.Dequeue());
}
}
}
public override void StartCreate(string ip, int port)
{
base.StartCreate(ip, port);
kGHeartBeatManage = new KGHeartBeatManage<ChatSession, KGHeartBeat>().InitTimerEvent(null, lost =>
{
if (lost != null && lost.mSocket != null && lost.mSocket.Connected)
{
(lost.SessionID + "ID心跳包超时 准备断开连接").KLog(LogLevel.Err);
lost.Clear();
}
}).StartTimer();
//添加新的会话事件
AddSessionEvent += v =>
{
kGHeartBeatManage.AddConnectDic(v);
};
//删除会话事件
RemoveSessionEvent += v =>
{
kGHeartBeatManage.RemoveConnectDic(v);
};
}
/// <summary>
/// 处理客户端发过来的消息
/// </summary>
/// <param name="pack"></param>
public void DisposePack(ChatDatasPack pack)
{
switch ((CMD)pack.chatDatas.Cmd)
{
//心跳包指令
case CMD.HeartBeat:
//更新心跳包
kGHeartBeatManage.UpdateOneHeat(pack.chatSession);
pack.chatSession.SendData(pack.chatDatas);
break;
//登录指令
case CMD.ReqLogin:
//判断在线的名字是否重复
if (IsUserOnLine(pack.chatDatas.PlayerName))
{
pack.chatDatas.Err = (int)ErrorInfo.NameRepeatsErr;
}
else
{
//返回指令
pack.chatDatas.Cmd = (int)CMD.RspLogin;
//存储角色的名字和头像图片数据
pack.chatSession.PlayerName = pack.chatDatas.PlayerName;
pack.chatSession.HeadData = pack.chatDatas.HeadData;
}
//返回消息给客户端
pack.chatSession.SendData(pack.chatDatas);
break;
//聊天指令
case CMD.ReqChatInfo:
//返回指令
pack.chatDatas.Cmd = (int)CMD.RspChatInfo;
//赋值角色的名字和头像图片数据
pack.chatDatas.PlayerName = pack.chatSession.PlayerName;
pack.chatDatas.HeadData = pack.chatSession.HeadData;
//发回给自身聊天
pack.chatSession.SendData(pack.chatDatas);
//改成对方
pack.chatDatas.Chatdata.Islocal = 1;
//分发到各个客户端 聊天消息
SessionList.Where(v => v != pack.chatSession).ToList().ForEach(v =>
{
(v.mSocket.Connected).ToString().KLog();
v.SendData(pack.chatDatas);
});
break;
}
}
/// <summary>
/// 这里是添加处理客户端消息任务队列
/// </summary>
/// <param name="session"></param>
/// <param name="chatData"></param>
public void AddDataPackQue(ChatSession session, ChatDatas chatData)
{
lock (obj)
{
DataPackQue.Enqueue(new ChatDatasPack { chatSession = session, chatDatas = chatData });
}
}
}
}
增加的部分1.指令 添加多了一个HeartBeat的指令
[C#] 纯文本查看 复制代码 namespace ChatNetData{
public enum CMD {
None,
HeartBeat,
ReqLogin,
ReqChatInfo,
RspLogin,
RspChatInfo,
}}
2. 在ChatServe里声明持有一个KGHeartBeatManage进行初始化 在回应 添加多了一个HeartBeat的回应
[C#] 纯文本查看 复制代码 public void DisposePack(ChatDatasPack pack)
{
switch ((CMD)pack.chatDatas.Cmd)
{
//心跳包指令
case CMD.HeartBeat:
//更新心跳包
kGHeartBeatManage.UpdateOneHeat(pack.chatSession);
pack.chatSession.SendData(pack.chatDatas);
break;
}
}
貌似就差不多了AddSessionEvent/RemoveSessionEvent是 添加客户端 删除客户端的事件回调 这里回调之后可以直接用AddConnectDic/RemoveConnectDic 进行增删心跳包数据
InitTimerEvent 进行初始化 然后进行开启.StartTimer
客户端客户端这边增加的也挺少 先把Tool dll拖进来工程 然后增加部分全在GameRoot
GameRoot全部代码 = =貌似上传不了代码 直接文件吧
GameRoot.txt
(7.16 KB, 下载次数: 260)
|