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

消除TimerComponent每次udpate的gc

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

+ 1 - 1
Client-Server.sln

@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 15
-VisualStudioVersion = 15.0.27004.2009
+VisualStudioVersion = 15.0.27130.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unity.Plugins", "Unity\Unity.Plugins.csproj", "{D1FDB199-0FB7-099D-3771-C6A942E4E326}"
 EndProject

+ 1 - 0
Server/Hotfix/Handler/G2G_LockRequestHandler.cs

@@ -16,6 +16,7 @@ namespace Hotfix
 				{
 					response.Error = ErrorCode.ERR_NotFoundUnit;
 					reply(response);
+					return;
 				}
 
 				await unit.GetComponent<MasterComponent>().Lock(message.Address);

+ 2 - 2
Server/Hotfix/System/NetOuterComponentSystem.cs

@@ -26,14 +26,14 @@ namespace Hotfix
 	{
 		public static void Awake(this NetOuterComponent self)
 		{
-			self.Awake(NetworkProtocol.TCP);
+			self.Awake(NetworkProtocol.KCP);
 			self.MessagePacker = new ProtobufPacker();
 			self.MessageDispatcher = new OuterMessageDispatcher();
 		}
 
 		public static void Awake(this NetOuterComponent self, IPEndPoint ipEndPoint)
 		{
-			self.Awake(NetworkProtocol.TCP, ipEndPoint);
+			self.Awake(NetworkProtocol.KCP, ipEndPoint);
 			self.MessagePacker = new ProtobufPacker();
 			self.MessageDispatcher = new OuterMessageDispatcher();
 		}

+ 17 - 3
Server/Model/Component/ActorProxyComponent.cs

@@ -5,7 +5,7 @@ namespace Model
 	[ObjectEvent]
 	public class ActorProxyComponentEvent : ObjectEvent<ActorProxyComponent>, IStart
 	{
-		// 每分钟扫描一次过期的actorproxy进行回收,过期时间是5分钟
+		// 每10s扫描一次过期的actorproxy进行回收,过期时间是1分钟
 		public async void Start()
 		{
 			ActorProxyComponent self = this.Get();
@@ -14,7 +14,7 @@ namespace Model
 
 			while (true)
 			{
-				await Game.Scene.GetComponent<TimerComponent>().WaitAsync(60000);
+				await Game.Scene.GetComponent<TimerComponent>().WaitAsync(1000);
 
 				if (self.Id == 0)
 				{
@@ -32,7 +32,7 @@ namespace Model
 						continue;
 					}
 
-					if (timeNow < actorProxy.LastSendTime + 5 * 60000)
+					if (timeNow < actorProxy.LastSendTime + 10000)
 					{
 						continue;
 					}
@@ -52,6 +52,20 @@ namespace Model
 	{
 		public readonly Dictionary<long, ActorProxy> ActorProxys = new Dictionary<long, ActorProxy>();
 
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+			base.Dispose();
+			foreach (ActorProxy actorProxy in this.ActorProxys.Values)
+			{
+				actorProxy.Dispose();
+			}
+			this.ActorProxys.Clear();
+		}
+
 		public ActorProxy Get(long id)
 		{
 			if (this.ActorProxys.TryGetValue(id, out ActorProxy actorProxy))

+ 2 - 2
Server/Model/Component/BenchmarkComponent.cs

@@ -26,7 +26,7 @@ namespace Model
 				NetOuterComponent networkComponent = Game.Scene.GetComponent<NetOuterComponent>();
 				for (int i = 0; i < 1000; i++)
 				{
-					await Game.Scene.GetComponent<TimerComponent>().WaitAsync(1000);
+					await Game.Scene.GetComponent<TimerComponent>().WaitAsync(100);
 					this.TestAsync(networkComponent, ipEndPoint, i);
 				}
 			}
@@ -43,7 +43,7 @@ namespace Model
 				using (Session session = networkComponent.Create(ipEndPoint))
 				{
 					int i = 0;
-					while (i < 1000000000)
+					while (i < 100000000)
 					{
 						++i;
 						await this.Send(session, j);

+ 35 - 33
Server/Model/Entity/ActorProxy.cs

@@ -123,16 +123,45 @@ namespace Model
 			this.tcs = null;
 			this.CancellationTokenSource = new CancellationTokenSource();
 		}
-		
-		public void Start()
+
+		public override void Dispose()
+		{
+			if (this.Id == 0)
+			{
+				return;
+			}
+
+			base.Dispose();
+			this.LastSendTime = 0;
+			this.Address = null;
+			this.RunningTasks.Clear();
+			this.WaitingTasks.Clear();
+			this.failTimes = 0;
+			var t = this.tcs;
+			this.tcs = null;
+			t?.SetResult(null);
+		}
+
+		public async void Start()
 		{
+			int appId = await Game.Scene.GetComponent<LocationProxyComponent>().Get(this.Id);
+			this.Address = Game.Scene.GetComponent<StartConfigComponent>().Get(appId).GetComponent<InnerConfig>().Address;
+
 			this.UpdateAsync();
 		}
 
 		private void Add(ActorTask task)
 		{
+			if (this.Id == 0)
+			{
+				throw new Exception("ActorProxy Disposed! dont hold actorproxy");
+			}
 			this.WaitingTasks.Enqueue(task);
-			this.AllowGet();
+			// failtimes > 0表示正在重试,这时候不能加到正在发送队列
+			if (this.failTimes == 0)
+			{
+				this.AllowGet();
+			}
 		}
 
 		private void Remove()
@@ -147,8 +176,7 @@ namespace Model
 			{
 				return;
 			}
-
-
+			
 			ActorTask task = this.WaitingTasks.Dequeue();
 			this.RunningTasks.Enqueue(task);
 
@@ -172,18 +200,13 @@ namespace Model
 
 		private async void UpdateAsync()
 		{
-			if (this.Address == null)
-			{
-				int appId = await Game.Scene.GetComponent<LocationProxyComponent>().Get(this.Id);
-				this.Address = Game.Scene.GetComponent<StartConfigComponent>().Get(appId).GetComponent<InnerConfig>().Address;
-			}
 			while (true)
 			{
+				ActorTask actorTask = await this.GetAsync();
 				if (this.Id == 0)
 				{
 					return;
 				}
-				ActorTask actorTask = await this.GetAsync();
 				if (actorTask == null)
 				{
 					return;
@@ -233,7 +256,6 @@ namespace Model
 						Game.Scene.GetComponent<ActorProxyComponent>().Remove(this.Id);
 						return;
 					}
-					
 					// 等待一会再发送
 					await Game.Scene.GetComponent<TimerComponent>().WaitAsync(this.failTimes * 500);
 					int appId = await Game.Scene.GetComponent<LocationProxyComponent>().Get(this.Id);
@@ -244,6 +266,7 @@ namespace Model
 				}
 
 				// 发送成功
+				this.LastSendTime = TimeHelper.Now();
 				this.failTimes = 0;
 				if (this.WindowSize < MaxWindowSize)
 				{
@@ -259,14 +282,12 @@ namespace Model
 
 		public void Send(AMessage message)
 		{
-			this.LastSendTime = TimeHelper.Now();
 			ActorMessageTask task = new ActorMessageTask(this, message);
 			this.Add(task);
 		}
 
 		public Task<Response> Call<Response>(ARequest request)where Response : AResponse
 		{
-			this.LastSendTime = TimeHelper.Now();
 			ActorRpcTask<Response> task = new ActorRpcTask<Response>(this, request);
 			this.Add(task);
 			return task.Tcs.Task;
@@ -298,24 +319,5 @@ namespace Model
 			}
 			return s;
 		}
-
-		public override void Dispose()
-		{
-			if (this.Id == 0)
-			{
-				return;
-			}
-
-			base.Dispose();
-
-			this.LastSendTime = 0;
-			this.Address = "";
-			this.RunningTasks.Clear();
-			this.WaitingTasks.Clear();
-			this.failTimes = 0;
-			var t = this.tcs;
-			this.tcs = null;
-			t?.SetResult(null);
-		}
 	}
 }

+ 16 - 5
Unity/Assets/Scripts/Base/MultiMap.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Model
 {
@@ -9,12 +10,9 @@ namespace Model
 		// 重用list
 		private readonly Queue<List<K>> queue = new Queue<List<K>>();
 
-		public SortedDictionary<T, List<K>>.KeyCollection Keys
+		public SortedDictionary<T, List<K>> GetDictionary()
 		{
-			get
-			{
-				return this.dictionary.Keys;
-			}
+			return this.dictionary;
 		}
 
 		public void Add(T t, K k)
@@ -29,6 +27,19 @@ namespace Model
 			this.dictionary[t] = list;
 		}
 
+		public KeyValuePair<T, List<K>> First()
+		{
+			return this.dictionary.First();
+		}
+
+		public int Count
+		{
+			get
+			{
+				return this.dictionary.Count;
+			}
+		}
+
 		private List<K> FetchList()
 		{
 			if (this.queue.Count > 0)

+ 0 - 2
Unity/Assets/Scripts/Base/Network/AService.cs

@@ -13,8 +13,6 @@ namespace Model
 
 	public abstract class AService: IDisposable
 	{
-		public abstract void Add(Action action);
-
 		public abstract AChannel GetChannel(long id);
 
 		public abstract Task<AChannel> AcceptChannel();

+ 0 - 2
Unity/Assets/Scripts/Base/Network/KNet/KChannel.cs

@@ -143,9 +143,7 @@ namespace Model
 				this.OnError(this, SocketError.Disconnecting);
 				return;
 			}
-
 			this.kcp.Update(timeNow);
-
 			uint nextUpdateTime = this.kcp.Check(timeNow);
 			this.GetService().AddToNextTimeUpdate(nextUpdateTime, this.Id);
 		}

+ 11 - 17
Unity/Assets/Scripts/Base/Network/KNet/KService.cs

@@ -33,7 +33,6 @@ namespace Model
 
 		// 下次时间更新的channel
 		private readonly MultiMap<long, long> timerMap = new MultiMap<long, long>();
-		private readonly Queue<long> timeoutTimer = new Queue<long>();
 
 		public KService(IPEndPoint ipEndPoint)
 		{
@@ -211,11 +210,7 @@ namespace Model
 		{
 			this.timerMap.Add(time, id);
 		}
-
-		public override void Add(Action action)
-		{
-		}
-
+		
 		public override AChannel GetChannel(long id)
 		{
 			KChannel channel;
@@ -254,26 +249,25 @@ namespace Model
 		public override void Update()
 		{
 			this.TimeNow = (uint)TimeHelper.Now();
-			
-			foreach (long time in this.timerMap.Keys)
+
+			while (true)
 			{
-				if (time > this.TimeNow)
+				if (this.timerMap.Count <= 0)
 				{
 					break;
 				}
-				this.timeoutTimer.Enqueue(time);
-			}
-			while (this.timeoutTimer.Count > 0)
-			{
-				long key = this.timeoutTimer.Dequeue();
-				List<long> timeOutId = this.timerMap[key];
+				var kv = this.timerMap.First();
+				if (kv.Key > TimeNow)
+				{
+					break;
+				}
+				List<long> timeOutId = kv.Value;
 				foreach (long id in timeOutId)
 				{
 					this.updateChannels.Add(id);
 				}
-				this.timerMap.Remove(key);
+				this.timerMap.Remove(kv.Key);
 			}
-
 			foreach (long id in updateChannels)
 			{
 				KChannel kChannel;

+ 1 - 6
Unity/Assets/Scripts/Base/Network/TNet/TService.cs

@@ -43,12 +43,7 @@ namespace Model
 			this.acceptor.Stop();
 			this.acceptor = null;
 		}
-
-		public override void Add(Action action)
-		{
-			this.actions.Enqueue(action);
-		}
-
+		
 		public override AChannel GetChannel(long id)
 		{
 			TChannel channel = null;

+ 0 - 4
Unity/Assets/Scripts/Base/Network/UNet/UService.cs

@@ -60,10 +60,6 @@ namespace Model
 			return channel;
 		}
 
-		public override void Add(Action action)
-		{
-		}
-
 		public override AChannel GetChannel(long id)
 		{
 			UChannel channel = null;

+ 1 - 1
Unity/Assets/Scripts/Component/NetOuterComponent.cs

@@ -18,7 +18,7 @@
 	{
 		public void Awake()
 		{
-			this.Awake(NetworkProtocol.TCP);
+			this.Awake(NetworkProtocol.KCP);
 			this.MessagePacker = new ProtobufPacker();
 			this.MessageDispatcher = new ClientDispatcher();
 		}

+ 12 - 12
Unity/Assets/Scripts/Component/TimerComponent.cs

@@ -20,7 +20,7 @@ namespace Model
 		}
 	}
 
-	public class TimerComponent: Component
+	public class TimerComponent : Component
 	{
 		private readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
 
@@ -29,24 +29,23 @@ namespace Model
 		/// </summary>
 		private readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
 
-		private readonly EQueue<long> timeoutTimer = new EQueue<long>();
-
 		public void Update()
 		{
 			long timeNow = TimeHelper.Now();
-			foreach (long time in this.timeId.Keys)
+
+			while (true)
 			{
-				if (time > timeNow)
+				if (this.timeId.Count <= 0)
+				{
+					return;
+				}
+				var kv = this.timeId.First();
+				if (kv.Key > timeNow)
 				{
 					break;
 				}
-				this.timeoutTimer.Enqueue(time);
-			}
 
-			while (this.timeoutTimer.Count > 0)
-			{
-				long key = this.timeoutTimer.Dequeue();
-				List<long> timeOutId = this.timeId[key];
+				List<long> timeOutId = kv.Value;
 				foreach (long id in timeOutId)
 				{
 					Timer timer;
@@ -56,7 +55,8 @@ namespace Model
 					}
 					timer.tcs.SetResult(true);
 				}
-				this.timeId.Remove(key);
+
+				this.timeId.Remove(kv.Key);
 			}
 		}
 

+ 1 - 1
Unity/Unity.Editor.Plugins.csproj

@@ -7,7 +7,7 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{81A6E58E-BFF2-F1C8-1C4E-6316985F642C}</ProjectGuid>
     <OutputType>Library</OutputType>
-    <AssemblyName>Assembly-CSharp-Editor-firstpass.dll</AssemblyName>
+    <AssemblyName>Assembly-CSharp-Editor-firstpass</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>

+ 1 - 1
Unity/Unity.Editor.csproj

@@ -7,7 +7,7 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{C17F48D3-964E-E97C-3D2E-966F7A6C6D93}</ProjectGuid>
     <OutputType>Library</OutputType>
-    <AssemblyName>Assembly-CSharp-Editor.dll</AssemblyName>
+    <AssemblyName>Assembly-CSharp-Editor</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>

+ 1 - 1
Unity/Unity.Plugins.csproj

@@ -7,7 +7,7 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{D1FDB199-0FB7-099D-3771-C6A942E4E326}</ProjectGuid>
     <OutputType>Library</OutputType>
-    <AssemblyName>Assembly-CSharp-firstpass.dll</AssemblyName>
+    <AssemblyName>Assembly-CSharp-firstpass</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>

+ 5 - 8
Unity/Unity.csproj

@@ -7,20 +7,17 @@
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{CF118143-7E37-744F-BE45-3F55345FEC40}</ProjectGuid>
     <OutputType>Library</OutputType>
-    <AssemblyName>Assembly-CSharp.dll</AssemblyName>
+    <AssemblyName>Assembly-CSharp</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <ProjectTypeGuids>{E097FAD1-6243-4DAD-9C02-E9B9EFC3FFC1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
     <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
-    <TargetFrameworkProfile>
-    </TargetFrameworkProfile>
-    <CompilerResponseFile>
-    </CompilerResponseFile>
+    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <CompilerResponseFile></CompilerResponseFile>
     <UnityProjectType>Game:1</UnityProjectType>
     <UnityBuildTarget>iOS:9</UnityBuildTarget>
     <UnityVersion>2017.1.1p4</UnityVersion>
-    <RootNamespace>
-    </RootNamespace>
+    <RootNamespace></RootNamespace>
     <LangVersion>6</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
@@ -587,4 +584,4 @@
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Target Name="GenerateTargetFrameworkMonikerAttribute" />
-</Project>
+</Project>