Bladeren bron

完善了消息发送和分发模块

tanghai 10 jaren geleden
bovenliggende
commit
5f2b81b2ae

+ 3 - 2
CSharp/Game/Controller/Controller.csproj

@@ -48,8 +48,9 @@
     <Compile Include="ConfigCategory\NodeCategory.cs" />
     <Compile Include="ConfigCategory\ServerInfoCategory.cs" />
     <Compile Include="ConfigCategory\UnitCategory.cs" />
-    <Compile Include="Event\LogicMessageEvent.cs" />
-    <Compile Include="Event\GateMessageEvent.cs" />
+    <Compile Include="Event\GateRecvServerMessageEvent.cs" />
+    <Compile Include="Event\LogicRecvMessageEvent.cs" />
+    <Compile Include="Event\GateRecvClientMessageEvent.cs" />
     <Compile Include="Factory\UnitFactory.cs" />
     <Compile Include="Message\CMsgLoginEvent.cs" />
     <Compile Include="NodeType.cs" />

+ 3 - 9
CSharp/Game/Controller/Event/GateMessageEvent.cs → CSharp/Game/Controller/Event/GateRecvClientMessageEvent.cs

@@ -4,8 +4,8 @@ using Model;
 
 namespace Controller
 {
-	[Event(EventType.GateMessage, ServerType.Gate)]
-	public class GateMessageEvent : IEventSync
+	[Event(EventType.GateRecvClientMessage, ServerType.Gate)]
+	public class GateRecvClientMessageEvent : IEventSync
 	{
 		public void Run(Env env)
 		{
@@ -13,14 +13,8 @@ namespace Controller
 			AChannel channel = env.Get<AChannel>(EnvKey.Channel);
 
 			// 进行消息分发
-			int opcode = BitConverter.ToUInt16(message, 0);
-			if (!MessageTypeHelper.IsClientMessage(opcode))
-			{
-				return;
-			}
-
 			ChannelUnitInfoComponent channelUnitInfoComponent = channel.GetComponent<ChannelUnitInfoComponent>();
-			byte[] idBuffer = channelUnitInfoComponent.PlayerId.ToByteArray();
+			byte[] idBuffer = channelUnitInfoComponent.UnitId.ToByteArray();
 			byte[] buffer = new byte[message.Length + 12];
 			Array.Copy(message, 0, buffer, 0, 4);
 			Array.Copy(idBuffer, 0, buffer, 4, idBuffer.Length);

+ 23 - 0
CSharp/Game/Controller/Event/GateRecvServerMessageEvent.cs

@@ -0,0 +1,23 @@
+using System;
+using Model;
+using MongoDB.Bson;
+
+namespace Controller
+{
+	[Event(EventType.GateRecvServerMessage, ServerType.Gate)]
+	public class GateRecvServerMessageEvent : IEventSync
+	{
+		public void Run(Env env)
+		{
+			byte[] message = env.Get<byte[]>(EnvKey.Message);
+			byte[] idBuffer = new byte[12];
+			Array.Copy(message, 2, idBuffer, 0, 12);
+			ObjectId unitId = new ObjectId(idBuffer);
+
+			byte[] buffer = new byte[message.Length - 12];
+			Array.Copy(message, 0, buffer, 0, 2);
+			Array.Copy(message, 14, buffer, 2, message.Length - 14);
+			World.Instance.GetComponent<GateNetworkComponent>().SendAsync(unitId, buffer);
+		}
+	}
+}

+ 2 - 2
CSharp/Game/Controller/Event/LogicMessageEvent.cs → CSharp/Game/Controller/Event/LogicRecvMessageEvent.cs

@@ -4,8 +4,8 @@ using MongoDB.Bson;
 
 namespace Controller
 {
-	[Event(EventType.Message, ServerType.All)]
-	public class LogicMessageEvent : IEventSync
+	[Event(EventType.LogicRecvMessage, ServerType.All)]
+	public class LogicRecvMessageEvent : IEventSync
 	{
 		public void Run(Env env)
 		{

+ 3 - 3
CSharp/Game/Controller/Message/CMsgLoginEvent.cs

@@ -20,10 +20,10 @@ namespace Controller.Message
 			Unit unit = World.Instance.GetComponent<FactoryComponent<Unit>>().Create(UnitType.GatePlayer, 1);
 
 			AChannel channel = env.Get<AChannel>(EnvKey.Channel);
-			ChannelUnitInfoComponent channelUnitInfoComponent =
-					channel.AddComponent<ChannelUnitInfoComponent>();
+			ChannelUnitInfoComponent channelUnitInfoComponent = channel.AddComponent<ChannelUnitInfoComponent>();
 			channelUnitInfoComponent.Account = cmsg.Account;
-			channelUnitInfoComponent.PlayerId = unit.Id;
+			channelUnitInfoComponent.UnitId = unit.Id;
+			World.Instance.GetComponent<GateNetworkComponent>().AssociateUnitIdAndChannel(unit.Id, channel);
 		}
 	}
 }

+ 1 - 1
CSharp/Game/Model/Component/ChannelUnitInfoComponent.cs

@@ -10,7 +10,7 @@ namespace Model
 	public class ChannelUnitInfoComponent: Component<AChannel>
 	{
 		public byte[] Account { get; set; }
-		public ObjectId PlayerId { get; set; }
+		public ObjectId UnitId { get; set; }
 		public string ServerName { get; set; }
 	}
 }

+ 40 - 1
CSharp/Game/Model/Component/GateNetworkComponent.cs

@@ -1,6 +1,8 @@
 using System;
+using System.Collections.Generic;
 using Common.Base;
 using Common.Network;
+using MongoDB.Bson;
 using TNet;
 using UNet;
 
@@ -13,6 +15,8 @@ namespace Model
 	{
 		private IService service;
 
+		private readonly Dictionary<ObjectId, AChannel> unitIdChannels = new Dictionary<ObjectId, AChannel>();
+
 		private void Accept(string host, int port, NetworkProtocol protocol = NetworkProtocol.TCP)
 		{
 			switch (protocol)
@@ -49,6 +53,7 @@ namespace Model
 			while (true)
 			{
 				AChannel channel = await this.service.GetChannel();
+				channel.OnDispose += this.OnChannelDispose;
 				ProcessChannel(channel);
 			}
 		}
@@ -65,9 +70,43 @@ namespace Model
 				Env env = new Env();
 				env[EnvKey.Channel] = channel;
 				env[EnvKey.Message] = message;
+				int opcode = BitConverter.ToUInt16(message, 0);
+
+				if (!MessageTypeHelper.IsClientMessage(opcode))
+				{
+					continue;
+				}
+
+				World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.GateRecvClientMessage, env);
+			}
+		}
+
+		// channel删除的时候需要清除与unit id的关联
+		private void OnChannelDispose(AChannel channel)
+		{
+			ChannelUnitInfoComponent channelUnitInfoComponent =
+					channel.GetComponent<ChannelUnitInfoComponent>();
+			if (channelUnitInfoComponent != null)
+			{
+				this.unitIdChannels.Remove(channelUnitInfoComponent.UnitId);
+			}
+		}
+
+		// 将unit id与channel关联起来
+		public void AssociateUnitIdAndChannel(ObjectId id, AChannel channel)
+		{
+			this.unitIdChannels[id] = channel;
+		}
 
-				World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.GateMessage, env);
+		public void SendAsync(ObjectId id, byte[] buffer)
+		{
+			AChannel channel;
+			if (!this.unitIdChannels.TryGetValue(id, out channel))
+			{
+				return;
 			}
+
+			channel.SendAsync(buffer);
 		}
 	}
 }

+ 36 - 3
CSharp/Game/Model/Component/NetworkComponent.cs

@@ -4,7 +4,6 @@ using System.Threading.Tasks;
 using Common.Base;
 using Common.Helper;
 using Common.Network;
-using MongoDB.Bson;
 using TNet;
 using UNet;
 
@@ -18,6 +17,8 @@ namespace Model
 
 		private readonly Dictionary<int, Action<byte[], bool>> requestCallback = new Dictionary<int, Action<byte[], bool>>();
 
+		private readonly Dictionary<string, Queue<byte[]>> cache = new Dictionary<string, Queue<byte[]>>();
+
 		private void Accept(string host, int port, NetworkProtocol protocol = NetworkProtocol.TCP)
 		{
 			switch (protocol)
@@ -80,14 +81,46 @@ namespace Model
 					continue;
 				}
 
+				// 如果是发给client的消息,说明这是gate server,需要根据unitid查到channel,进行发送
+				if (MessageTypeHelper.IsServerMessage(opcode))
+				{
+					World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.GateRecvServerMessage, env);
+					continue;
+				}
+
 				// 进行消息分发
-				World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.GateMessage, env);
+				World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.LogicRecvMessage, env);
 			}
 		}
 
 		public async void SendAsync(string address, byte[] buffer)
 		{
-			
+			Queue<byte[]> queue;
+			AChannel channel;
+			// 连接已存在
+			if (this.service.HasChannel(address))
+			{
+				channel = await this.service.GetChannel(address);
+				channel.SendAsync(buffer);
+				return;
+			}
+
+			// 连接不存在,但是处于正在连接过程中
+			if (this.cache.TryGetValue(address, out queue))
+			{
+				queue.Enqueue(buffer);
+				return;
+			}
+
+			// 连接不存在,需要启动连接
+			queue = new Queue<byte[]>();
+			queue.Enqueue(buffer);
+			this.cache[address] = queue;
+			channel = await this.service.GetChannel(address);
+			while (queue.Count > 0)
+			{
+				channel.SendAsync(queue.Dequeue());
+			}
 		}
 
 		// 消息回调或者超时回调

+ 3 - 3
CSharp/Game/Model/EventType.cs

@@ -7,8 +7,8 @@
 		public const int BeforeRemoveBuff = 2;
 		public const int AfterRemoveBuff = 3;
 		public const int BuffTimeout = 4;
-		public const int Message = 5;
-
-		public const int GateMessage = 6;
+		public const int LogicRecvMessage = 5;
+		public const int GateRecvClientMessage = 6;
+		public const int GateRecvServerMessage = 8;
 	}
 }

+ 2 - 0
CSharp/Platform/Common/Network/IService.cs

@@ -27,6 +27,8 @@ namespace Common.Network
 
 		Task<AChannel> GetChannel();
 
+		bool HasChannel(string address);
+
 		void Remove(AChannel channel);
 
 		void Update();

+ 5 - 0
CSharp/Platform/TNet/TService.cs

@@ -105,6 +105,11 @@ namespace TNet
 			return channel;
 		}
 
+		public bool HasChannel(string address)
+		{
+			return this.channels.ContainsKey(address);
+		}
+
 		public void Remove(AChannel channel)
 		{
 			TChannel tChannel = channel as TChannel;

+ 5 - 0
CSharp/Platform/UNet/UService.cs

@@ -114,6 +114,11 @@ namespace UNet
 			return channel;
 		}
 
+		public bool HasChannel(string address)
+		{
+			return this.channels.ContainsKey(address);
+		}
+
 		public void Remove(AChannel channel)
 		{
 			UChannel tChannel = channel as UChannel;