using System.Collections.Concurrent;
using System.Collections.Generic;
using MrWu.Debug;
using Server.Core;
using Server.Net;
namespace Server
{
///
/// 这个是主线程处理的
///
public class UserSessionManager : Singleton
{
///
/// 用户会话事件队列
///
private readonly ConcurrentQueue evtQueue = new ConcurrentQueue();
///
/// 用户的Session
///
private Dictionary UserSessions = new Dictionary();
public bool IsGame { get; private set; }
public UserSessionManager(bool isGame)
{
IsGame = isGame;
}
public void AddUserSessionEvt(UserSessionEvt evt)
{
evtQueue.Enqueue(evt);
}
public void Update()
{
int count = evtQueue.Count;
while (count -- > 0)
{
if (!evtQueue.TryDequeue(out var evt))
{
break;
}
switch (evt.EvtType)
{
case UserSessionEvtType.Connected:
{
UserSession userSession = new UserSession(evt.Id, evt.InstanceId);
if (UserSessions.ContainsKey(evt.Id))
{
Debug.Error($"怎么会存在这个链接实例:{evt.Id}");
}
userSession.IsDisConnected = false;
userSession.RemoteIPAddress = evt.RemoteIPAddress;
UserSessions[evt.Id] = userSession;
}
break;
case UserSessionEvtType.Fin:
{
//断开处理
if (UserSessions.TryGetValue(evt.Id, out UserSession userSession))
{
if (evt.InstanceId != userSession.InstanceId)
{
break;
}
UserFin(userSession);
}
}
break;
case UserSessionEvtType.ReceivePack:
{
if (UserSessions.TryGetValue(evt.Id,out UserSession userSession))
{
if (evt.InstanceId != userSession.InstanceId)
{
Debug.Error("实例ID改变,不处理消息!");
}
else
{
//要不这里就单独处理包,不走MessageDispatcher
userSession.RemoteIPAddress = evt.RemoteIPAddress;
evt.GamePacket.Session = ProxySession.Create(userSession);
MessageDispatcher.Instance.AddPack(evt.GamePacket);
}
}
else
{
Debug.Error("未找到收包的链接!");
}
}
break;
}
evt.Dispose();
}
}
///
/// 用户断开链接
///
public void UserFin(UserSession userSession)
{
if (UserSessions.TryGetValue(userSession.Id, out UserSession _session))
{
if (_session == userSession)
{
UserSessions.Remove(userSession.Id);
userSession.IsDisConnected = true;
int userid = 0;
if (userSession.UserData != null)
{
userid = userSession.UserData.Userid;
}
if (userSession.UserData != null && IsGame)
{
if (!GameSessionManager.Instance.RemovePlayerSession(userid, userSession))
{
Debug.Error($"玩家未正常移除! {userid}");
}
Debug.ImportantLog($"玩家离线,注销Session {userid}");
}
userSession.ClearUserData();
if (userid > 0)
{
GameDispatcher.Instance.Dispatch(GameMsgId.DisConnected, userid);
}
}
else
{
Debug.Info("移除失败,不是同一个Session!");
}
}
else
{
Debug.Info("移除失败,没找到Session!");
}
}
}
public class UserSessionEvt : Reference
{
///
/// 链接ID
///
public long Id { get; private set; }
///
/// 实例ID
///
public long InstanceId { get; private set; }
///
/// IP地址 链接的时候会赋值
///
///
public string RemoteIPAddress { get; private set; }
public GamePacket GamePacket { get; private set; }
public UserSessionEvtType EvtType { get; private set; }
public static UserSessionEvt Create(long id, long instanceId, string remoteIpAddress)
{
UserSessionEvt self =ReferencePool.Fetch();
self.Id = id;
self.InstanceId = instanceId;
self.RemoteIPAddress = remoteIpAddress;
self.EvtType = UserSessionEvtType.Connected;
return self;
}
public static UserSessionEvt Create(long id, long instanceId, GamePacket gamePacket,string remoteIpAddress)
{
UserSessionEvt self = ReferencePool.Fetch();
self.Id = id;
self.InstanceId = instanceId;
self.GamePacket = gamePacket;
self.RemoteIPAddress = remoteIpAddress;
self.EvtType = UserSessionEvtType.ReceivePack;
return self;
}
public static UserSessionEvt Create(long id,long instanceId,UserSessionEvtType evtType)
{
var evt = new UserSessionEvt();
evt.Id = id;
evt.InstanceId = instanceId;
evt.EvtType = evtType;
return evt;
}
public override void Dispose()
{
RemoteIPAddress = null;
GamePacket = null;
ReferencePool.Recycle(this);
}
}
public enum UserSessionEvtType
{
///
/// 链接
///
Connected,
///
/// 断开链接
///
Fin,
///
/// 收包
///
ReceivePack,
}
}