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

1.location完善了lock unlock调用,location保存到mongodb中
2.actor消息一个个处理,处理完一个才处理下一个

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

+ 1 - 1
Server/Hotfix/Message/ObjectLockRequestHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			ObjectLockResponse response = new ObjectLockResponse();
 			try
 			{
-				Game.Scene.GetComponent<LocationComponent>().Add(message.Key, session.RemoteAddress);
+				Game.Scene.GetComponent<LocationComponent>().LockAsync(message.Key, message.Time);
 				reply(response);
 			}
 			catch (Exception e)

+ 1 - 1
Server/Hotfix/Message/ObjectUnLockRequestHandler.cs

@@ -11,7 +11,7 @@ namespace Hotfix
 			ObjectUnLockResponse response = new ObjectUnLockResponse();
 			try
 			{
-				Game.Scene.GetComponent<LocationComponent>().UnLock(message.Key, message.Value);
+				Game.Scene.GetComponent<LocationComponent>().UpdateAndUnLock(message.Key, message.AppId, message.Value);
 				reply(response);
 			}
 			catch (Exception e)

+ 1 - 1
Server/Model/Component/ActorComponent.cs

@@ -79,7 +79,7 @@ namespace Model
 			while (true)
 			{
 				ActorMessageInfo info = await this.GetAsync();
-				this.entityActorHandler.Handle(info.Session, this.Owner, info.Message);
+				await this.entityActorHandler.Handle(info.Session, this.Owner, info.Message);
 			}
 		}
 

+ 4 - 3
Server/Model/Component/ActorMessageDispatherComponent.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Threading.Tasks;
 
 namespace Model
 {
@@ -70,14 +71,14 @@ namespace Model
 			return actorHandler;
 		}
 
-		public void Handle(Session session, Entity entity, IActorMessage message)
+		public async Task<bool> Handle(Session session, Entity entity, IActorMessage message)
 		{
 			if (!this.handlers.TryGetValue(message.GetType(), out IMActorHandler handler))
 			{
 				Log.Error($"not found message handler: {message.GetType().FullName}");
-				return;
+				return false;
 			}
-			handler.Handle(session, entity, message);
+			return await handler.Handle(session, entity, message);
 		}
 
 		public override void Dispose()

+ 48 - 16
Server/Model/Component/LocationComponent.cs

@@ -21,11 +21,14 @@ namespace Model
 	{
 		private readonly long key;
 
+		private readonly int time;
+
 		private readonly TaskCompletionSource<bool> tcs;
 
-		public LocationLockTask(long key)
+		public LocationLockTask(long key, int time)
 		{
 			this.key = key;
+			this.time = time;
 			this.tcs = new TaskCompletionSource<bool>();
 		}
 
@@ -41,7 +44,7 @@ namespace Model
 		{
 			try
 			{
-				Scene.GetComponent<LocationComponent>().Lock(this.key);
+				Scene.GetComponent<LocationComponent>().Lock(this.key, this.time);
 				this.tcs.SetResult(true);
 			}
 			catch (Exception e)
@@ -89,13 +92,16 @@ namespace Model
 	{
 		private readonly Dictionary<long, string> locations = new Dictionary<long, string>();
 
-		private readonly HashSet<long> lockSet = new HashSet<long>();
+		private readonly Dictionary<long, int> lockDict = new Dictionary<long, int>();
 
 		private readonly Dictionary<long, Queue<LocationTask>> taskQueues = new Dictionary<long, Queue<LocationTask>>();
 
-		public void Add(long key, string address)
+		public async void Add(long key, string address)
 		{
 			this.locations[key] = address;
+
+			// 更新db
+			await Game.Scene.GetComponent<DBProxyComponent>().Save(new Location(key, address));
 		}
 
 		public void Remove(long key)
@@ -109,20 +115,46 @@ namespace Model
 			return location;
 		}
 
-		public void Lock(long key)
+		public async void Lock(long key, int appId, int time = 0)
 		{
-			if (this.lockSet.Contains(key))
+			if (this.lockDict.ContainsKey(key))
 			{
 				return;
 			}
-			this.lockSet.Add(key);
+			this.lockDict.Add(key, appId);
+
+			// 超时则解锁
+			if (time > 0)
+			{
+				await Game.Scene.GetComponent<TimerComponent>().WaitAsync(time);
+
+				int saveAppId = 0;
+				this.lockDict.TryGetValue(key, out saveAppId);
+				if (saveAppId != appId)
+				{
+					Log.Warning($"unlock appid is different {saveAppId} {appId}");
+					return;
+				}
+				this.UnLock(key);
+			}
 		}
 
-		public void UnLock(long key, string value)
+		public void UpdateAndUnLock(long key, int appId, string value)
 		{
-			this.lockSet.Remove(key);
+			int saveAppId = 0;
+			this.lockDict.TryGetValue(key, out saveAppId);
+			if (saveAppId != appId)
+			{
+				Log.Warning($"unlock appid is different {saveAppId} {appId}" );
+				return;
+			}
+			this.Add(key, value);
+			this.UnLock(key);
+		}
 
-			this.locations[key] = value;
+		private void UnLock(long key)
+		{
+			this.lockDict.Remove(key);
 
 			if (!this.taskQueues.TryGetValue(key, out Queue<LocationTask> tasks))
 			{
@@ -136,7 +168,7 @@ namespace Model
 					this.taskQueues.Remove(key);
 					return;
 				}
-				if (this.lockSet.Contains(key))
+				if (this.lockDict.ContainsKey(key))
 				{
 					return;
 				}
@@ -146,22 +178,22 @@ namespace Model
 			}
 		}
 
-		public Task<bool> LockAsync(long key)
+		public Task<bool> LockAsync(long key, int time)
 		{
-			if (!this.lockSet.Contains(key))
+			if (!this.lockDict.ContainsKey(key))
 			{
-				this.Lock(key);
+				this.Lock(key, time);
 				return Task.FromResult(true);
 			}
 
-			LocationLockTask task = new LocationLockTask(key);
+			LocationLockTask task = new LocationLockTask(key, time);
 			this.AddTask(key, task);
 			return task.Task;
 		}
 
 		public Task<string> GetAsync(long key)
 		{
-			if (!this.lockSet.Contains(key))
+			if (!this.lockDict.ContainsKey(key))
 			{
 				this.locations.TryGetValue(key, out string location);
 				return Task.FromResult(location);

+ 17 - 1
Server/Model/Component/LocationProxyComponent.cs

@@ -15,9 +15,13 @@ namespace Model
 	{
 		public string LocationAddress;
 
+		public int AppId;
+
 		public void Awake()
 		{
-			this.LocationAddress = Game.Scene.GetComponent<StartConfigComponent>().LocationConfig.GetComponent<InnerConfig>().Address;
+			StartConfig startConfig = Game.Scene.GetComponent<StartConfigComponent>().LocationConfig;
+			this.AppId = startConfig.AppId;
+			this.LocationAddress = startConfig.GetComponent<InnerConfig>().Address;
 		}
 
 		public async Task Add(long key)
@@ -26,6 +30,18 @@ namespace Model
 			await session.Call<ObjectAddResponse>(new ObjectAddRequest() { Key = key });
 		}
 
+		public async Task Lock(long key, int time = 1000)
+		{
+			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.LocationAddress);
+			await session.Call<ObjectLockResponse>(new ObjectLockRequest() { Key = key, AppId = this.AppId, Time = time });
+		}
+
+		public async Task UnLock(long key, string value)
+		{
+			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.LocationAddress);
+			await session.Call<ObjectUnLockResponse>(new ObjectUnLockRequest() { Key = key, AppId = this.AppId, Value = value});
+		}
+
 		public async Task Remove(long key)
 		{
 			Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.LocationAddress);

+ 1 - 0
Server/Model/Entity/DBEntity.cs

@@ -5,6 +5,7 @@ namespace Model
 	[BsonIgnoreExtraElements]
 	[BsonKnownTypes(typeof(RechargeRecord))]
 	[BsonKnownTypes(typeof(Recharge))]
+	[BsonKnownTypes(typeof(Location))]
 	public class DBEntity: Entity
 	{
 		protected DBEntity()

+ 12 - 0
Server/Model/Entity/Location.cs

@@ -0,0 +1,12 @@
+namespace Model
+{
+	public class Location: DBEntity
+	{
+		public string Address;
+
+		public Location(long id, string address): base(id)
+		{
+			this.Address = address;
+		}
+	}
+}

+ 2 - 2
Server/Model/Entity/Message/InnerMessage.cs

@@ -56,11 +56,11 @@ namespace Model
{
	[Message(Opcode.R2G_GetLoginKey)]
	[BsonIgnoreExtraElements]
 
 	[Message(Opcode.ObjectRemoveResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectRemoveResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectLockRequest : ARequest
	{
		public long Key { get; set; }
	}
+	[Message(Opcode.ObjectLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectLockRequest : ARequest
	{
		public long Key { get; set; }
		public int AppId { get; set; }
		public int Time { get; set; }
	}
 
 	[Message(Opcode.ObjectLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectLockResponse : AResponse
	{
	}
 
-	[Message(Opcode.ObjectUnLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockRequest : ARequest
	{
		public long Key { get; set; }
		public string Value { get; set; }
	}
+	[Message(Opcode.ObjectUnLockRequest)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockRequest : ARequest
	{
		public long Key { get; set; }
		public int AppId { get; set; }
		public string Value { get; set; }
	}
 
 	[Message(Opcode.ObjectUnLockResponse)]
	[BsonIgnoreExtraElements]
	public class ObjectUnLockResponse : AResponse
	{
	}
 

+ 11 - 10
Server/Model/Message/AMActorHandler.cs

@@ -1,26 +1,27 @@
 using System;
+using System.Threading.Tasks;
 
 namespace Model
 {
 	public abstract class AMActorHandler<E, Message>: IMActorHandler where E: Entity where Message : AActorMessage
 	{
-		protected abstract void Run(E entity, Message message);
+		protected abstract Task<bool> Run(E entity, Message message);
 
-		public void Handle(Session session, Entity entity, object msg)
+		public async Task<bool> Handle(Session session, Entity entity, object msg)
 		{
 			Message message = msg as Message;
 			if (message == null)
 			{
 				Log.Error($"消息类型转换错误: {msg.GetType().FullName} to {typeof (Message).Name}");
-				return;
+				return false;
 			}
 			E e = entity as E;
 			if (e == null)
 			{
 				Log.Error($"Actor类型转换错误: {entity.GetType().Name} to {typeof(E).Name}");
-				return;
+				return false;
 			}
-			this.Run(e, message);
+			return await this.Run(e, message);
 		}
 
 		public Type GetMessageType()
@@ -39,9 +40,9 @@ namespace Model
 			reply(response);
 		}
 
-		protected abstract void Run(E entity, Request message, Action<Response> reply);
+		protected abstract Task<bool> Run(E entity, Request message, Action<Response> reply);
 
-		public void Handle(Session session, Entity entity,  object message)
+		public async Task<bool> Handle(Session session, Entity entity,  object message)
 		{
 			try
 			{
@@ -49,15 +50,15 @@ namespace Model
 				if (request == null)
 				{
 					Log.Error($"消息类型转换错误: {message.GetType().FullName} to {typeof (Request).Name}");
-					return;
+					return false;
 				}
 				E e = entity as E;
 				if (e == null)
 				{
 					Log.Error($"Actor类型转换错误: {entity.GetType().Name} to {typeof(E).Name}");
-					return;
+					return false;
 				}
-				this.Run(e, request, response =>
+				return await this.Run(e, request, response =>
 				{
 					// 等回调回来,session可以已经断开了,所以需要判断session id是否为0
 					if (session.Id == 0)

+ 7 - 4
Server/Model/Message/IEntityActorHandler.cs

@@ -1,8 +1,10 @@
+using System.Threading.Tasks;
+
 namespace Model
 {
 	public interface IEntityActorHandler
 	{
-		void Handle(Session session, Entity entity, IActorMessage message);
+		Task<bool> Handle(Session session, Entity entity, IActorMessage message);
 	}
 
 	/// <summary>
@@ -10,18 +12,19 @@ namespace Model
 	/// </summary>
 	public class GateSessionEntityActorHandler : IEntityActorHandler
 	{
-		public void Handle(Session session, Entity entity, IActorMessage message)
+		public async Task<bool> Handle(Session session, Entity entity, IActorMessage message)
 		{
 			message.Id = 0;
 			((Session)entity).Send((AMessage)message);
+			return true;
 		}
 	}
 
 	public class CommonEntityActorHandler : IEntityActorHandler
 	{
-		public void Handle(Session session, Entity entity, IActorMessage message)
+		public async Task<bool> Handle(Session session, Entity entity, IActorMessage message)
 		{
-			Game.Scene.GetComponent<ActorMessageDispatherComponent>().Handle(session, entity, message);
+			return await Game.Scene.GetComponent<ActorMessageDispatherComponent>().Handle(session, entity, message);
 		}
 	}
 }

+ 2 - 1
Server/Model/Message/IMActorHandler.cs

@@ -1,10 +1,11 @@
 using System;
+using System.Threading.Tasks;
 
 namespace Model
 {
 	public interface IMActorHandler
 	{
-		void Handle(Session session, Entity entity, object message);
+		Task<bool> Handle(Session session, Entity entity, object message);
 		Type GetMessageType();
 	}
 }

+ 1 - 0
Server/Model/Server.Model.csproj

@@ -70,6 +70,7 @@
     <Compile Include="Component\ActorProxyComponent.cs" />
     <Compile Include="Component\GamerComponent.cs" />
     <Compile Include="Entity\Gamer.cs" />
+    <Compile Include="Entity\Location.cs" />
     <Compile Include="Message\IEntityActorHandler.cs" />
     <Compile Include="Component\OpcodeTypeComponent.cs" />
     <Compile Include="Component\ActorManagerComponent.cs" />