|
@@ -2,16 +2,10 @@
|
|
|
using System.Collections.Generic;
|
|
using System.Collections.Generic;
|
|
|
using System.Net;
|
|
using System.Net;
|
|
|
using System.Threading.Tasks;
|
|
using System.Threading.Tasks;
|
|
|
|
|
+using ETModel;
|
|
|
|
|
|
|
|
-namespace ETModel
|
|
|
|
|
|
|
+namespace ETHotfix
|
|
|
{
|
|
{
|
|
|
- public enum LockStatus
|
|
|
|
|
- {
|
|
|
|
|
- LockedNot,
|
|
|
|
|
- LockRequesting,
|
|
|
|
|
- Locked,
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
[ObjectSystem]
|
|
[ObjectSystem]
|
|
|
public class LockComponentAwakeSystem : AwakeSystem<LockComponent, IPEndPoint>
|
|
public class LockComponentAwakeSystem : AwakeSystem<LockComponent, IPEndPoint>
|
|
|
{
|
|
{
|
|
@@ -24,92 +18,87 @@ namespace ETModel
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
/// 分布式锁组件,Unit对象可能在不同进程上有镜像,访问该对象的时候需要对他加锁
|
|
/// 分布式锁组件,Unit对象可能在不同进程上有镜像,访问该对象的时候需要对他加锁
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
- public class LockComponent: Component
|
|
|
|
|
|
|
+ public static class LockComponentEx
|
|
|
{
|
|
{
|
|
|
- private LockStatus status = LockStatus.LockedNot;
|
|
|
|
|
- private IPEndPoint address;
|
|
|
|
|
- private int lockCount;
|
|
|
|
|
- private readonly Queue<TaskCompletionSource<bool>> queue = new Queue<TaskCompletionSource<bool>>();
|
|
|
|
|
-
|
|
|
|
|
- public void Awake(IPEndPoint addr)
|
|
|
|
|
|
|
+ public static void Awake(this LockComponent self, IPEndPoint addr)
|
|
|
{
|
|
{
|
|
|
- this.address = addr;
|
|
|
|
|
|
|
+ self.address = addr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public async Task Lock()
|
|
|
|
|
|
|
+ public static async Task Lock(this LockComponent self)
|
|
|
{
|
|
{
|
|
|
- ++this.lockCount;
|
|
|
|
|
|
|
+ ++self.lockCount;
|
|
|
|
|
|
|
|
- if (this.status == LockStatus.Locked)
|
|
|
|
|
|
|
+ if (self.status == LockStatus.Locked)
|
|
|
{
|
|
{
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- if (this.status == LockStatus.LockRequesting)
|
|
|
|
|
|
|
+ if (self.status == LockStatus.LockRequesting)
|
|
|
{
|
|
{
|
|
|
- await WaitLock();
|
|
|
|
|
|
|
+ await self.WaitLock();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- this.status = LockStatus.LockRequesting;
|
|
|
|
|
|
|
+ self.status = LockStatus.LockRequesting;
|
|
|
|
|
|
|
|
// 真身直接本地请求锁,镜像需要调用Rpc获取锁
|
|
// 真身直接本地请求锁,镜像需要调用Rpc获取锁
|
|
|
- MasterComponent masterComponent = this.Entity.GetComponent<MasterComponent>();
|
|
|
|
|
|
|
+ MasterComponent masterComponent = self.Entity.GetComponent<MasterComponent>();
|
|
|
if (masterComponent != null)
|
|
if (masterComponent != null)
|
|
|
{
|
|
{
|
|
|
- await masterComponent.Lock(this.address);
|
|
|
|
|
|
|
+ await masterComponent.Lock(self.address);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- RequestLock();
|
|
|
|
|
- await WaitLock();
|
|
|
|
|
|
|
+ self.RequestLock();
|
|
|
|
|
+ await self.WaitLock();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private Task<bool> WaitLock()
|
|
|
|
|
|
|
+ private static Task<bool> WaitLock(this LockComponent self)
|
|
|
{
|
|
{
|
|
|
- if (this.status == LockStatus.Locked)
|
|
|
|
|
|
|
+ if (self.status == LockStatus.Locked)
|
|
|
{
|
|
{
|
|
|
return Task.FromResult(true);
|
|
return Task.FromResult(true);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
|
|
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
|
|
|
- this.queue.Enqueue(tcs);
|
|
|
|
|
|
|
+ self.queue.Enqueue(tcs);
|
|
|
return tcs.Task;
|
|
return tcs.Task;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private async void RequestLock()
|
|
|
|
|
|
|
+ private static async void RequestLock(this LockComponent self)
|
|
|
{
|
|
{
|
|
|
try
|
|
try
|
|
|
{
|
|
{
|
|
|
- Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.address);
|
|
|
|
|
|
|
+ Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.address);
|
|
|
string serverAddress = Game.Scene.GetComponent<StartConfigComponent>().StartConfig.ServerIP;
|
|
string serverAddress = Game.Scene.GetComponent<StartConfigComponent>().StartConfig.ServerIP;
|
|
|
- G2G_LockRequest request = new G2G_LockRequest { Id = this.Entity.Id, Address = serverAddress };
|
|
|
|
|
|
|
+ G2G_LockRequest request = new G2G_LockRequest { Id = self.Entity.Id, Address = serverAddress };
|
|
|
await session.Call(request);
|
|
await session.Call(request);
|
|
|
|
|
|
|
|
- this.status = LockStatus.Locked;
|
|
|
|
|
|
|
+ self.status = LockStatus.Locked;
|
|
|
|
|
|
|
|
- foreach (TaskCompletionSource<bool> taskCompletionSource in this.queue)
|
|
|
|
|
|
|
+ foreach (TaskCompletionSource<bool> taskCompletionSource in self.queue)
|
|
|
{
|
|
{
|
|
|
taskCompletionSource.SetResult(true);
|
|
taskCompletionSource.SetResult(true);
|
|
|
}
|
|
}
|
|
|
- this.queue.Clear();
|
|
|
|
|
|
|
+ self.queue.Clear();
|
|
|
}
|
|
}
|
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
|
{
|
|
{
|
|
|
- Log.Error($"获取锁失败: {this.address} {this.Entity.Id} {e}");
|
|
|
|
|
|
|
+ Log.Error($"获取锁失败: {self.address} {self.Entity.Id} {e}");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public async Task Release()
|
|
|
|
|
|
|
+ public static async Task Release(this LockComponent self)
|
|
|
{
|
|
{
|
|
|
- --this.lockCount;
|
|
|
|
|
- if (this.lockCount != 0)
|
|
|
|
|
|
|
+ --self.lockCount;
|
|
|
|
|
+ if (self.lockCount != 0)
|
|
|
{
|
|
{
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- this.status = LockStatus.LockedNot;
|
|
|
|
|
- Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(this.address);
|
|
|
|
|
|
|
+ self.status = LockStatus.LockedNot;
|
|
|
|
|
+ Session session = Game.Scene.GetComponent<NetInnerComponent>().Get(self.address);
|
|
|
G2G_LockReleaseRequest request = new G2G_LockReleaseRequest();
|
|
G2G_LockReleaseRequest request = new G2G_LockReleaseRequest();
|
|
|
await session.Call(request);
|
|
await session.Call(request);
|
|
|
}
|
|
}
|