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, } }