Просмотр исходного кода

1.数据库操作可以操作component
2.对象池,不从池中取就不应该回收到池
3.优化MultiMap,减少gc

tanghai 8 лет назад
Родитель
Сommit
68c2f85bd5

+ 4 - 4
Server/Hotfix/Handler/DBQueryBatchRequestHandler.cs

@@ -13,15 +13,15 @@ namespace Hotfix
 			try
 			{
 				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
-				List<Entity> entitys = await dbCacheComponent.GetBatch(message.CollectionName, message.IdList);
+				List<Disposer> disposers = await dbCacheComponent.GetBatch(message.CollectionName, message.IdList);
 
-				response.Entitys = entitys;
+				response.Disposers = disposers;
 
 				if (message.NeedCache)
 				{
-					foreach (Entity entity in entitys)
+					foreach (Disposer disposer in disposers)
 					{
-						dbCacheComponent.AddToCache(entity, message.CollectionName);
+						dbCacheComponent.AddToCache(disposer, message.CollectionName);
 					}
 				}
 

+ 4 - 4
Server/Hotfix/Handler/DBQueryJsonRequestHandler.cs

@@ -13,15 +13,15 @@ namespace Hotfix
 			try
 			{
 				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
-				List<Entity> entitys = await dbCacheComponent.GetJson(message.CollectionName, message.Json);
+				List<Disposer> disposers = await dbCacheComponent.GetJson(message.CollectionName, message.Json);
 
-				response.Entitys = entitys;
+				response.Disposers = disposers;
 
 				if (message.NeedCache)
 				{
-					foreach (Entity entity in entitys)
+					foreach (Disposer disposer in disposers)
 					{
-						dbCacheComponent.AddToCache(entity, message.CollectionName);
+						dbCacheComponent.AddToCache(disposer, message.CollectionName);
 					}
 				}
 

+ 4 - 4
Server/Hotfix/Handler/DBQueryRequestHandler.cs

@@ -12,13 +12,13 @@ namespace Hotfix
 			try
 			{
 				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
-				Entity entity = await dbCacheComponent.Get(message.CollectionName, message.Id);
+				Disposer disposer = await dbCacheComponent.Get(message.CollectionName, message.Id);
 
-				response.Entity = entity;
+				response.Disposer = disposer;
 
-				if (message.NeedCache && entity != null)
+				if (message.NeedCache && disposer != null)
 				{
-					dbCacheComponent.AddToCache(entity, message.CollectionName);
+					dbCacheComponent.AddToCache(disposer, message.CollectionName);
 				}
 
 				reply(response);

+ 4 - 4
Server/Hotfix/Handler/DBSaveBatchRequestHandler.cs

@@ -15,18 +15,18 @@ namespace Hotfix
 
 				if (message.CollectionName == "")
 				{
-					message.CollectionName = message.Entitys[0].GetType().Name;
+					message.CollectionName = message.Disposers[0].GetType().Name;
 				}
 
 				if (message.NeedCache)
 				{
-					foreach (Entity entity in message.Entitys)
+					foreach (Disposer disposer in message.Disposers)
 					{
-						dbCacheComponent.AddToCache(entity, message.CollectionName);
+						dbCacheComponent.AddToCache(disposer, message.CollectionName);
 					}
 				}
 
-				await dbCacheComponent.AddBatch(message.Entitys, message.CollectionName);
+				await dbCacheComponent.AddBatch(message.Disposers, message.CollectionName);
 
 				reply(response);
 			}

+ 3 - 3
Server/Hotfix/Handler/DBSaveRequestHandler.cs

@@ -14,14 +14,14 @@ namespace Hotfix
 				DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
 				if (message.CollectionName == "")
 				{
-					message.CollectionName = message.Entity.GetType().Name;
+					message.CollectionName = message.Disposer.GetType().Name;
 				}
 
 				if (message.NeedCache)
 				{
-					dbCacheComponent.AddToCache(message.Entity, message.CollectionName);
+					dbCacheComponent.AddToCache(message.Disposer, message.CollectionName);
 				}
-				await dbCacheComponent.Add(message.Entity, message.CollectionName);
+				await dbCacheComponent.Add(message.Disposer, message.CollectionName);
 				reply(response);
 			}
 			catch (Exception e)

+ 30 - 30
Server/Model/Component/DBCacheComponent.cs

@@ -17,7 +17,7 @@ namespace Model
 	/// </summary>
 	public class DBCacheComponent : Component
 	{
-		public Dictionary<string, Dictionary<long, Entity>> cache = new Dictionary<string, Dictionary<long, Entity>>();
+		public Dictionary<string, Dictionary<long, Disposer>> cache = new Dictionary<string, Dictionary<long, Disposer>>();
 
 		public const int taskCount = 32;
 		public List<DBTaskQueue> tasks = new List<DBTaskQueue>(taskCount);
@@ -31,53 +31,53 @@ namespace Model
 			}
 		}
 
-		public Task<bool> Add(Entity entity, string collectionName = "")
+		public Task<bool> Add(Disposer disposer, string collectionName = "")
 		{
 			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
 
-			this.AddToCache(entity, collectionName);
+			this.AddToCache(disposer, collectionName);
 
 			if (collectionName == "")
 			{
-				collectionName = entity.GetType().Name;
+				collectionName = disposer.GetType().Name;
 			}
-			DBSaveTask task = EntityFactory.CreateWithId<DBSaveTask, Entity, string, TaskCompletionSource<bool>>(entity.Id, entity, collectionName, tcs);
+			DBSaveTask task = EntityFactory.CreateWithId<DBSaveTask, Disposer, string, TaskCompletionSource<bool>>(disposer.Id, disposer, collectionName, tcs);
 			this.tasks[(int)((ulong)task.Id % taskCount)].Add(task);
 
 			return tcs.Task;
 		}
 
-		public Task<bool> AddBatch(List<Entity> entitys, string collectionName)
+		public Task<bool> AddBatch(List<Disposer> disposers, string collectionName)
 		{
 			TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-			DBSaveBatchTask task = EntityFactory.Create<DBSaveBatchTask, List<Entity>, string, TaskCompletionSource<bool>>(entitys, collectionName, tcs);
+			DBSaveBatchTask task = EntityFactory.Create<DBSaveBatchTask, List<Disposer>, string, TaskCompletionSource<bool>>(disposers, collectionName, tcs);
 			this.tasks[(int)((ulong)task.Id % taskCount)].Add(task);
 			return tcs.Task;
 		}
 
-		public void AddToCache(Entity entity, string collectionName = "")
+		public void AddToCache(Disposer disposer, string collectionName = "")
 		{
 			if (collectionName == "")
 			{
-				collectionName = entity.GetType().Name;
+				collectionName = disposer.GetType().Name;
 			}
-			Dictionary<long, Entity> collection;
+			Dictionary<long, Disposer> collection;
 			if (!this.cache.TryGetValue(collectionName, out collection))
 			{
-				collection = new Dictionary<long, Entity>();
+				collection = new Dictionary<long, Disposer>();
 				this.cache.Add(collectionName, collection);
 			}
-			collection[entity.Id] = entity;
+			collection[disposer.Id] = disposer;
 		}
 
-		public Entity GetFromCache(string collectionName, long id)
+		public Disposer GetFromCache(string collectionName, long id)
 		{
-			Dictionary<long, Entity> d;
+			Dictionary<long, Disposer> d;
 			if (!this.cache.TryGetValue(collectionName, out d))
 			{
 				return null;
 			}
-			Entity result;
+			Disposer result;
 			if (!d.TryGetValue(id, out result))
 			{
 				return null;
@@ -87,7 +87,7 @@ namespace Model
 
 		public void RemoveFromCache(string collectionName, long id)
 		{
-			Dictionary<long, Entity> d;
+			Dictionary<long, Disposer> d;
 			if (!this.cache.TryGetValue(collectionName, out d))
 			{
 				return;
@@ -95,53 +95,53 @@ namespace Model
 			d.Remove(id);
 		}
 
-		public Task<Entity> Get(string collectionName, long id)
+		public Task<Disposer> Get(string collectionName, long id)
 		{
-			Entity entity = GetFromCache(collectionName, id);
+			Disposer entity = GetFromCache(collectionName, id);
 			if (entity != null)
 			{
 				return Task.FromResult(entity);
 			}
 
-			TaskCompletionSource<Entity> tcs = new TaskCompletionSource<Entity>();
-			DBQueryTask dbQueryTask = EntityFactory.CreateWithId<DBQueryTask, string, TaskCompletionSource<Entity>>(id, collectionName, tcs);
+			TaskCompletionSource<Disposer> tcs = new TaskCompletionSource<Disposer>();
+			DBQueryTask dbQueryTask = EntityFactory.CreateWithId<DBQueryTask, string, TaskCompletionSource<Disposer>>(id, collectionName, tcs);
 			this.tasks[(int)((ulong)id % taskCount)].Add(dbQueryTask);
 
 			return tcs.Task;
 		}
 
-		public Task<List<Entity>> GetBatch(string collectionName, List<long> idList)
+		public Task<List<Disposer>> GetBatch(string collectionName, List<long> idList)
 		{
-			List <Entity> entitys = new List<Entity>();
+			List <Disposer> disposers = new List<Disposer>();
 			bool isAllInCache = true;
 			foreach (long id in idList)
 			{
-				Entity entity = this.GetFromCache(collectionName, id);
+				Disposer entity = this.GetFromCache(collectionName, id);
 				if (entity == null)
 				{
 					isAllInCache = false;
 					break;
 				}
-				entitys.Add(entity);
+				disposers.Add(entity);
 			}
 
 			if (isAllInCache)
 			{
-				return Task.FromResult(entitys);
+				return Task.FromResult(disposers);
 			}
 
-			TaskCompletionSource<List<Entity>> tcs = new TaskCompletionSource<List<Entity>>();
-			DBQueryBatchTask dbQueryBatchTask = EntityFactory.Create<DBQueryBatchTask, List<long>, string, TaskCompletionSource<List<Entity>>>(idList, collectionName, tcs);
+			TaskCompletionSource<List<Disposer>> tcs = new TaskCompletionSource<List<Disposer>>();
+			DBQueryBatchTask dbQueryBatchTask = EntityFactory.Create<DBQueryBatchTask, List<long>, string, TaskCompletionSource<List<Disposer>>>(idList, collectionName, tcs);
 			this.tasks[(int)((ulong)dbQueryBatchTask.Id % taskCount)].Add(dbQueryBatchTask);
 
 			return tcs.Task;
 		}
 
-		public Task<List<Entity>> GetJson(string collectionName, string json)
+		public Task<List<Disposer>> GetJson(string collectionName, string json)
 		{
-			TaskCompletionSource<List<Entity>> tcs = new TaskCompletionSource<List<Entity>>();
+			TaskCompletionSource<List<Disposer>> tcs = new TaskCompletionSource<List<Disposer>>();
 			
-			DBQueryJsonTask dbQueryJsonTask = EntityFactory.Create<DBQueryJsonTask, string, string, TaskCompletionSource< List < Entity >>>(collectionName, json, tcs);
+			DBQueryJsonTask dbQueryJsonTask = EntityFactory.Create<DBQueryJsonTask, string, string, TaskCompletionSource<List<Disposer>>>(collectionName, json, tcs);
 			this.tasks[(int)((ulong)dbQueryJsonTask.Id % taskCount)].Add(dbQueryJsonTask);
 
 			return tcs.Task;

+ 13 - 13
Server/Model/Component/DBProxyComponent.cs

@@ -26,35 +26,35 @@ namespace Model
 			dbAddress = dbStartConfig.GetComponent<InnerConfig>().Address;
 		}
 
-		public async Task Save(Entity entity, bool needCache = true)
+		public async Task Save(Disposer disposer, bool needCache = true)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
-			await session.Call<DBSaveResponse>(new DBSaveRequest { Entity = entity, NeedCache = needCache});
+			await session.Call<DBSaveResponse>(new DBSaveRequest { Disposer = disposer, NeedCache = needCache});
 		}
 
-		public async Task SaveBatch(List<Entity> entitys, bool needCache = true)
+		public async Task SaveBatch(List<Disposer> disposers, bool needCache = true)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
-			await session.Call<DBSaveBatchResponse>(new DBSaveBatchRequest { Entitys = entitys, NeedCache = needCache});
+			await session.Call<DBSaveBatchResponse>(new DBSaveBatchRequest { Disposers = disposers, NeedCache = needCache});
 		}
 
-		public async Task Save(Entity entity, bool needCache, CancellationToken cancellationToken)
+		public async Task Save(Disposer disposer, bool needCache, CancellationToken cancellationToken)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
-			await session.Call<DBSaveResponse>(new DBSaveRequest { Entity = entity, NeedCache = needCache}, cancellationToken);
+			await session.Call<DBSaveResponse>(new DBSaveRequest { Disposer = disposer, NeedCache = needCache}, cancellationToken);
 		}
 
-		public async void SaveLog(Entity entity)
+		public async void SaveLog(Disposer disposer)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
-			await session.Call<DBSaveResponse>(new DBSaveRequest { Entity = entity,  NeedCache = false, CollectionName = "Log" });
+			await session.Call<DBSaveResponse>(new DBSaveRequest { Disposer = disposer,  NeedCache = false, CollectionName = "Log" });
 		}
 
 		public async Task<T> Query<T>(long id, bool needCache = true) where T: Entity
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
 			DBQueryResponse dbQueryResponse = await session.Call<DBQueryResponse>(new DBQueryRequest { CollectionName = typeof(T).Name, Id = id, NeedCache = needCache });
-			return (T)dbQueryResponse.Entity;
+			return (T)dbQueryResponse.Disposer;
 		}
 
 		public async Task<List<T>> QueryBatch<T>(List<long> ids, bool needCache = true) where T : Entity
@@ -62,9 +62,9 @@ namespace Model
 			List<T> list = new List<T>();
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
 			DBQueryBatchResponse dbQueryBatchResponse = await session.Call<DBQueryBatchResponse>(new DBQueryBatchRequest { CollectionName = typeof(T).Name, IdList = ids, NeedCache = needCache});
-			foreach (Entity entity in dbQueryBatchResponse.Entitys)
+			foreach (Disposer disposer in dbQueryBatchResponse.Disposers)
 			{
-				list.Add((T)entity);
+				list.Add((T)disposer);
 			}
 			return list;
 		}
@@ -74,9 +74,9 @@ namespace Model
 			List<T> list = new List<T>();
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(dbAddress);
 			DBQueryJsonResponse dbQueryJsonResponse = await session.Call<DBQueryJsonResponse>(new DBQueryJsonRequest { CollectionName = typeof(T).Name, Json = json, NeedCache = needCache});
-			foreach (Entity entity in dbQueryJsonResponse.Entitys)
+			foreach (Disposer disposer in dbQueryJsonResponse.Disposers)
 			{
-				list.Add((T)entity);
+				list.Add((T)disposer);
 			}
 			return list;
 		}

+ 10 - 10
Server/Model/Entity/DBQueryBatchTask.cs

@@ -7,9 +7,9 @@ using MongoDB.Driver;
 namespace Model
 {
 	[ObjectEvent]
-	public class DBQueryBatchTaskEvent : ObjectEvent<DBQueryBatchTask>, IAwake<List<long>, string, TaskCompletionSource<List<Entity>>>
+	public class DBQueryBatchTaskEvent : ObjectEvent<DBQueryBatchTask>, IAwake<List<long>, string, TaskCompletionSource<List<Disposer>>>
 	{
-		public void Awake(List<long> idList, string collectionName, TaskCompletionSource<List<Entity>> tcs)
+		public void Awake(List<long> idList, string collectionName, TaskCompletionSource<List<Disposer>> tcs)
 		{
 			DBQueryBatchTask self = this.Get();
 
@@ -25,31 +25,31 @@ namespace Model
 
 		public List<long> IdList { get; set; }
 
-		public TaskCompletionSource<List<Entity>> Tcs { get; set; }
+		public TaskCompletionSource<List<Disposer>> Tcs { get; set; }
 		
 		public override async Task Run()
 		{
 			DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
-			List<Entity> result = new List<Entity>();
+			List<Disposer> result = new List<Disposer>();
 
 			try
 			{
 				// 执行查询数据库任务
 				foreach (long id in IdList)
 				{
-					Entity entity = dbCacheComponent.GetFromCache(this.CollectionName, id);
-					if (entity == null)
+					Disposer disposer = dbCacheComponent.GetFromCache(this.CollectionName, id);
+					if (disposer == null)
 					{
-						entity = await dbComponent.GetCollection(this.CollectionName).FindAsync((s) => s.Id == id).Result.FirstOrDefaultAsync();
-						dbCacheComponent.AddToCache(entity);
+						disposer = await dbComponent.GetCollection(this.CollectionName).FindAsync((s) => s.Id == id).Result.FirstOrDefaultAsync();
+						dbCacheComponent.AddToCache(disposer);
 					}
 					
-					if (entity == null)
+					if (disposer == null)
 					{
 						continue;
 					}
-					result.Add(entity);
+					result.Add(disposer);
 				}
 				
 				this.Tcs.SetResult(result);

+ 10 - 10
Server/Model/Entity/DBQueryTask.cs

@@ -5,9 +5,9 @@ using MongoDB.Driver;
 namespace Model
 {
 	[ObjectEvent]
-	public class DBQueryTaskEvent : ObjectEvent<DBQueryTask>, IAwake<string, TaskCompletionSource<Entity>>
+	public class DBQueryTaskEvent : ObjectEvent<DBQueryTask>, IAwake<string, TaskCompletionSource<Disposer>>
 	{
-		public void Awake(string collectionName, TaskCompletionSource<Entity> tcs)
+		public void Awake(string collectionName, TaskCompletionSource<Disposer> tcs)
 		{
 			DBQueryTask self = this.Get();
 			self.CollectionName = collectionName;
@@ -19,7 +19,7 @@ namespace Model
 	{
 		public string CollectionName { get; set; }
 
-		public TaskCompletionSource<Entity> Tcs { get; set; }
+		public TaskCompletionSource<Disposer> Tcs { get; set; }
 
 		public DBQueryTask(long id): base(id)
 		{
@@ -30,21 +30,21 @@ namespace Model
 			DBCacheComponent dbCacheComponent = Game.Scene.GetComponent<DBCacheComponent>();
 			DBComponent dbComponent = Game.Scene.GetComponent<DBComponent>();
 			// 执行查询前先看看cache中是否已经存在
-			Entity entity = dbCacheComponent.GetFromCache(this.CollectionName, this.Id);
-			if (entity != null)
+			Disposer disposer = dbCacheComponent.GetFromCache(this.CollectionName, this.Id);
+			if (disposer != null)
 			{
-				this.Tcs.SetResult(entity);
+				this.Tcs.SetResult(disposer);
 				return;
 			}
 			try
 			{
 				// 执行查询数据库任务
-				entity = await dbComponent.GetCollection(this.CollectionName).FindAsync((s) => s.Id == this.Id).Result.FirstOrDefaultAsync();
-				if (entity != null)
+				disposer = await dbComponent.GetCollection(this.CollectionName).FindAsync((s) => s.Id == this.Id).Result.FirstOrDefaultAsync();
+				if (disposer != null)
 				{
-					dbCacheComponent.AddToCache(entity);
+					dbCacheComponent.AddToCache(disposer);
 				}
-				this.Tcs.SetResult(entity);
+				this.Tcs.SetResult(disposer);
 			}
 			catch (Exception e)
 			{

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
Server/Model/Entity/Message/InnerMessage.cs


+ 34 - 2
Unity/Assets/Scripts/Base/MultiMap.cs

@@ -6,6 +6,9 @@ namespace Model
 	{
 		private readonly SortedDictionary<T, List<K>> dictionary = new SortedDictionary<T, List<K>>();
 
+		// 重用list
+		private readonly Queue<List<K>> queue = new Queue<List<K>>();
+
 		public SortedDictionary<T, List<K>>.KeyCollection Keys
 		{
 			get
@@ -20,12 +23,34 @@ namespace Model
 			this.dictionary.TryGetValue(t, out list);
 			if (list == null)
 			{
-				list = new List<K>();
+				list = this.FetchList();
 			}
 			list.Add(k);
 			this.dictionary[t] = list;
 		}
 
+		private List<K> FetchList()
+		{
+			if (this.queue.Count > 0)
+			{
+				List<K> list = this.queue.Dequeue();
+				list.Clear();
+				return list;
+			}
+			return new List<K>();
+		}
+
+		private void RecycleList(List<K> list)
+		{
+			// 防止暴涨
+			if (this.queue.Count > 100)
+			{
+				return;
+			}
+			list.Clear();
+			this.queue.Enqueue(list);
+		}
+
 		public bool Remove(T t, K k)
 		{
 			List<K> list;
@@ -40,6 +65,7 @@ namespace Model
 			}
 			if (list.Count == 0)
 			{
+				this.RecycleList(list);
 				this.dictionary.Remove(t);
 			}
 			return true;
@@ -47,6 +73,12 @@ namespace Model
 
 		public bool Remove(T t)
 		{
+			List<K> list = null;
+			this.dictionary.TryGetValue(t, out list);
+			if (list != null)
+			{
+				this.RecycleList(list);
+			}
 			return this.dictionary.Remove(t);
 		}
 
@@ -85,7 +117,7 @@ namespace Model
 		{
 			List<K> list;
 			this.dictionary.TryGetValue(t, out list);
-			if ((list != null) && (list.Count > 0))
+			if (list != null && list.Count > 0)
 			{
 				return list[0];
 			}

+ 9 - 1
Unity/Assets/Scripts/Base/Object/Disposer.cs

@@ -3,6 +3,8 @@ using MongoDB.Bson.Serialization.Attributes;
 
 namespace Model
 {
+	[BsonKnownTypes(typeof(Entity))]
+	[BsonKnownTypes(typeof(Component))]
 	public abstract class Disposer : Object, IDisposable
 	{
 		[BsonIgnoreIfDefault]
@@ -10,6 +12,9 @@ namespace Model
 		[BsonElement]
 		[BsonId]
 		public long Id { get; set; }
+
+		[BsonIgnore]
+		public bool IsFromPool { get; set; }
 	
 		protected Disposer()
 		{
@@ -26,7 +31,10 @@ namespace Model
 		public virtual void Dispose()
 		{
 			this.Id = 0;
-			ObjectPool.Instance.Recycle(this);
+			if (this.IsFromPool)
+			{
+				ObjectPool.Instance.Recycle(this);
+			}
 		}
 	}
 }

+ 1 - 3
Unity/Assets/Scripts/Base/Object/EntityFactory.cs

@@ -1,6 +1,4 @@
-using System;
-
-namespace Model
+namespace Model
 {
 	public static class EntityFactory
 	{

+ 4 - 2
Unity/Assets/Scripts/Base/Object/ObjectPool.cs

@@ -47,8 +47,10 @@ namespace Model
 
         public T Fetch<T>() where T: Disposer
 		{
-            return (T) this.Fetch(typeof(T));
-        }
+            T t = (T) this.Fetch(typeof(T));
+			t.IsFromPool = true;
+			return t;
+		}
         
         public void Recycle(Disposer obj)
         {

+ 2 - 2
Unity/Assets/Scripts/Component/NetworkComponent.cs

@@ -79,7 +79,7 @@ namespace Model
 		public virtual async Task<Session> Accept()
 		{
 			AChannel channel = await this.Service.AcceptChannel();
-			Session session = new Session(this, channel);
+			Session session = EntityFactory.Create<Session, NetworkComponent, AChannel>(this, channel);
 			channel.ErrorCallback += (c, e) => { this.Remove(session.Id); };
 			this.sessions.Add(session.Id, session);
 			return session;
@@ -111,7 +111,7 @@ namespace Model
 			try
 			{
 				AChannel channel = this.Service.ConnectChannel(ipEndPoint);
-				Session session = new Session(this, channel);
+				Session session = EntityFactory.Create<Session, NetworkComponent, AChannel>(this, channel);
 				channel.ErrorCallback += (c, e) => { this.Remove(session.Id); };
 				this.sessions.Add(session.Id, session);
 				return session;

+ 41 - 21
Unity/Assets/Scripts/Entity/Session.cs

@@ -6,22 +6,57 @@ using System.Threading.Tasks;
 
 namespace Model
 {
+	[ObjectEvent]
+	public class SessionEvent : ObjectEvent<Session>, IAwake<NetworkComponent, AChannel>, IStart
+	{
+		public void Awake(NetworkComponent network, AChannel channel)
+		{
+			this.Get().Awake(network, channel);
+		}
+
+		public void Start()
+		{
+			this.Get().Start();
+		}
+	}
+
 	public sealed class Session : Entity
 	{
 		private static uint RpcId { get; set; }
-		private readonly NetworkComponent network;
+		private NetworkComponent network;
+		private AChannel channel;
+
 		private readonly Dictionary<uint, Action<object>> requestCallback = new Dictionary<uint, Action<object>>();
-		private readonly AChannel channel;
 		private readonly List<byte[]> byteses = new List<byte[]>() {new byte[0], new byte[0]};
 		
-		public Session(NetworkComponent network, AChannel channel)
+		public void Awake(NetworkComponent net, AChannel c)
+		{
+			this.network = net;
+			this.channel = c;
+			this.requestCallback.Clear();
+		}
+
+		public void Start()
 		{
-			this.network = network;
-			this.channel = channel;
-			
 			this.StartRecv();
 		}
 
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			long id = this.Id;
+
+			base.Dispose();
+
+			this.channel.Dispose();
+			this.network.Remove(id);
+			this.requestCallback.Clear();
+		}
+
 		public IPEndPoint RemoteAddress
 		{
 			get
@@ -318,20 +353,5 @@ namespace Model
 
 			channel.Send(this.byteses);
 		}
-
-		public override void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-
-			long id = this.Id;
-
-			base.Dispose();
-			
-			this.channel.Dispose();
-			this.network.Remove(id);
-		}
 	}
 }

Некоторые файлы не были показаны из-за большого количества измененных файлов