mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
合理化Address协议逻辑
合理化Address协议逻辑
This commit is contained in:
@@ -35,8 +35,8 @@ namespace TEngine.DataStructure
|
|||||||
if (layer <= rLevel)
|
if (layer <= rLevel)
|
||||||
{
|
{
|
||||||
var currentRight = cur.Right;
|
var currentRight = cur.Right;
|
||||||
cur.Right = new SkipTableNode<TValue>(sortKey, viceKey, key, value,
|
|
||||||
layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null);
|
cur.Right = new SkipTableNode<TValue>(sortKey, viceKey, key, value, layer == 1 ? cur.Index + 1 : 0, cur, cur.Right, null);
|
||||||
|
|
||||||
if (currentRight != null)
|
if (currentRight != null)
|
||||||
{
|
{
|
||||||
|
@@ -528,6 +528,7 @@ namespace TEngine
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Scene = scene;
|
||||||
#if TENGINE_NET
|
#if TENGINE_NET
|
||||||
RuntimeId = IdFactory.NextEntityId(scene.RouteId);
|
RuntimeId = IdFactory.NextEntityId(scene.RouteId);
|
||||||
#else
|
#else
|
||||||
@@ -546,7 +547,6 @@ namespace TEngine
|
|||||||
foreach (var entity in _treeDb)
|
foreach (var entity in _treeDb)
|
||||||
{
|
{
|
||||||
entity.Parent = this;
|
entity.Parent = this;
|
||||||
entity.Scene = scene;
|
|
||||||
entity.Deserialize(scene, resetId);
|
entity.Deserialize(scene, resetId);
|
||||||
_tree.Add(entity.GetType(), entity);
|
_tree.Add(entity.GetType(), entity);
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,6 @@ namespace TEngine
|
|||||||
foreach (var entity in _multiDb)
|
foreach (var entity in _multiDb)
|
||||||
{
|
{
|
||||||
entity.Parent = this;
|
entity.Parent = this;
|
||||||
entity.Scene = scene;
|
|
||||||
entity.Deserialize(scene, resetId);
|
entity.Deserialize(scene, resetId);
|
||||||
_multi.Add(entity.Id, (ISupportedMultiEntity)entity);
|
_multi.Add(entity.Id, (ISupportedMultiEntity)entity);
|
||||||
}
|
}
|
||||||
|
@@ -217,7 +217,7 @@ namespace TEngine
|
|||||||
|
|
||||||
StringBuilder infoBuilder = GetFormatString(type, logString);
|
StringBuilder infoBuilder = GetFormatString(type, logString);
|
||||||
|
|
||||||
if (type == LogLevel.ERROR || type == LogLevel.WARNING || type == LogLevel.EXCEPTION)
|
if (type == LogLevel.ERROR || type == LogLevel.EXCEPTION)
|
||||||
{
|
{
|
||||||
StackFrame[] sf = new StackTrace().GetFrames();
|
StackFrame[] sf = new StackTrace().GetFrames();
|
||||||
for (int i = 0; i < sf.Length; i++)
|
for (int i = 0; i < sf.Length; i++)
|
||||||
|
@@ -26,6 +26,7 @@ namespace TEngine.Logic
|
|||||||
{
|
{
|
||||||
_session = (Session)Parent;
|
_session = (Session)Parent;
|
||||||
_selfRunTimeId = RuntimeId;
|
_selfRunTimeId = RuntimeId;
|
||||||
|
RepeatedSend().Coroutine();
|
||||||
_timerId = TimerScheduler.Instance.Unity.RepeatedTimer(interval, () => RepeatedSend().Coroutine());
|
_timerId = TimerScheduler.Instance.Unity.RepeatedTimer(interval, () => RepeatedSend().Coroutine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ namespace TEngine.Logic
|
|||||||
var responseTime = TimeHelper.Now;
|
var responseTime = TimeHelper.Now;
|
||||||
Ping = (int)(responseTime - requestTime) / 2;
|
Ping = (int)(responseTime - requestTime) / 2;
|
||||||
TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime;
|
TimeHelper.TimeDiff = pingResponse.Now + Ping - responseTime;
|
||||||
|
Log.Info("----------- HeartBeat -----------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,50 +1,26 @@
|
|||||||
#pragma warning disable CS8603
|
|
||||||
#pragma warning disable CS8600
|
|
||||||
#if TENGINE_NET
|
#if TENGINE_NET
|
||||||
namespace TEngine.Core.Network;
|
namespace TEngine.Core.Network;
|
||||||
|
|
||||||
public sealed class AddressableRouteComponentAwakeSystem : AwakeSystem<AddressableRouteComponent>
|
|
||||||
{
|
|
||||||
protected override void Awake(AddressableRouteComponent self)
|
|
||||||
{
|
|
||||||
self.Awake();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 可寻址消息组件、挂载了这个组件可以接收和发送Addressable消息
|
/// 可寻址消息组件、挂载了这个组件可以接收和发送Addressable消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class AddressableRouteComponent : Entity
|
public sealed class AddressableRouteComponent : Entity
|
||||||
{
|
{
|
||||||
private long _parentId;
|
private long _routeId;
|
||||||
private long _addressableRouteId;
|
private long _addressableId;
|
||||||
|
|
||||||
public static readonly CoroutineLockQueueType AddressableRouteMessageLock = new CoroutineLockQueueType("AddressableRouteMessageLock");
|
public static readonly CoroutineLockQueueType AddressableRouteMessageLock = new CoroutineLockQueueType("AddressableRouteMessageLock");
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
_parentId = 0;
|
_routeId = 0;
|
||||||
_addressableRouteId = 0;
|
_addressableId = 0;
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Awake()
|
public void SetAddressableId(long addressableId)
|
||||||
{
|
{
|
||||||
if (Parent == null)
|
_addressableId = addressableId;
|
||||||
{
|
|
||||||
throw new Exception("AddressableRouteComponent must be mounted under a component");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Parent.RuntimeId == 0)
|
|
||||||
{
|
|
||||||
throw new Exception("AddressableRouteComponent.Parent.RuntimeId is null");
|
|
||||||
}
|
|
||||||
|
|
||||||
_parentId = Parent.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAddressableRouteId(long addressableRouteId)
|
|
||||||
{
|
|
||||||
_addressableRouteId = addressableRouteId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IAddressableRouteMessage message)
|
public void Send(IAddressableRouteMessage message)
|
||||||
@@ -68,21 +44,21 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
var runtimeId = RuntimeId;
|
var runtimeId = RuntimeId;
|
||||||
IResponse iRouteResponse = null;
|
IResponse iRouteResponse = null;
|
||||||
|
|
||||||
using (await AddressableRouteMessageLock.Lock(_parentId, "AddressableRouteComponent Call MemoryStream"))
|
using (await AddressableRouteMessageLock.Lock(_addressableId, "AddressableRouteComponent Call MemoryStream"))
|
||||||
{
|
{
|
||||||
while (!IsDisposed)
|
while (!IsDisposed)
|
||||||
{
|
{
|
||||||
if (_addressableRouteId == 0)
|
if (_routeId == 0)
|
||||||
{
|
{
|
||||||
_addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, _parentId);
|
_routeId = await AddressableHelper.GetAddressableRouteId(Scene, _addressableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_addressableRouteId == 0)
|
if (_routeId == 0)
|
||||||
{
|
{
|
||||||
return MessageDispatcherSystem.Instance.CreateResponse(requestType, CoreErrorCode.ErrNotFoundRoute);
|
return MessageDispatcherSystem.Instance.CreateResponse(requestType, CoreErrorCode.ErrNotFoundRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
iRouteResponse = await MessageHelper.CallInnerRoute(Scene, _addressableRouteId, routeTypeOpCode, requestType, request);
|
iRouteResponse = await MessageHelper.CallInnerRoute(Scene, _routeId, routeTypeOpCode, requestType, request);
|
||||||
|
|
||||||
if (runtimeId != RuntimeId)
|
if (runtimeId != RuntimeId)
|
||||||
{
|
{
|
||||||
@@ -99,7 +75,7 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
{
|
{
|
||||||
if (++failCount > 20)
|
if (++failCount > 20)
|
||||||
{
|
{
|
||||||
Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {_addressableRouteId} AddressableRouteComponent:{Id}");
|
Log.Error($"AddressableComponent.Call failCount > 20 route send message fail, routeId: {_routeId} AddressableRouteComponent:{Id}");
|
||||||
return iRouteResponse;
|
return iRouteResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +86,7 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
iRouteResponse.ErrorCode = CoreErrorCode.ErrRouteTimeout;
|
iRouteResponse.ErrorCode = CoreErrorCode.ErrRouteTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
_addressableRouteId = 0;
|
_routeId = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -134,21 +110,21 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
var failCount = 0;
|
var failCount = 0;
|
||||||
var runtimeId = RuntimeId;
|
var runtimeId = RuntimeId;
|
||||||
|
|
||||||
using (await AddressableRouteMessageLock.Lock(_parentId,"AddressableRouteComponent Call"))
|
using (await AddressableRouteMessageLock.Lock(_addressableId,"AddressableRouteComponent Call"))
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (_addressableRouteId == 0)
|
if (_routeId == 0)
|
||||||
{
|
{
|
||||||
_addressableRouteId = await AddressableHelper.GetAddressableRouteId(Scene, _parentId);
|
_routeId = await AddressableHelper.GetAddressableRouteId(Scene, _addressableId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_addressableRouteId == 0)
|
if (_routeId == 0)
|
||||||
{
|
{
|
||||||
return MessageDispatcherSystem.Instance.CreateResponse(request, CoreErrorCode.ErrNotFoundRoute);
|
return MessageDispatcherSystem.Instance.CreateResponse(request, CoreErrorCode.ErrNotFoundRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
var iRouteResponse = await MessageHelper.CallInnerRoute(Scene, _addressableRouteId, request);
|
var iRouteResponse = await MessageHelper.CallInnerRoute(Scene, _routeId, request);
|
||||||
|
|
||||||
if (runtimeId != RuntimeId)
|
if (runtimeId != RuntimeId)
|
||||||
{
|
{
|
||||||
@@ -161,7 +137,7 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
{
|
{
|
||||||
if (++failCount > 20)
|
if (++failCount > 20)
|
||||||
{
|
{
|
||||||
Log.Error($"AddressableRouteComponent.Call failCount > 20 route send message fail, routeId: {_addressableRouteId} AddressableRouteComponent:{Id}");
|
Log.Error($"AddressableRouteComponent.Call failCount > 20 route send message fail, routeId: {_routeId} AddressableRouteComponent:{Id}");
|
||||||
return iRouteResponse;
|
return iRouteResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +148,7 @@ public sealed class AddressableRouteComponent : Entity
|
|||||||
iRouteResponse.ErrorCode = CoreErrorCode.ErrRouteTimeout;
|
iRouteResponse.ErrorCode = CoreErrorCode.ErrRouteTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
_addressableRouteId = 0;
|
_routeId = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case CoreErrorCode.ErrRouteTimeout:
|
case CoreErrorCode.ErrRouteTimeout:
|
||||||
|
@@ -144,7 +144,7 @@ namespace TEngine.Core.Network
|
|||||||
scene = entity.Scene;
|
scene = entity.Scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Error($"SceneWorld:{session.Scene.World.Id} SceneRouteId:{scene.RouteId} SceneType:{scene.SceneInfo.SceneType} EntityId {tEntity.Id} : Error {e}");
|
Log.Error($"SceneWorld:{session.Scene.World?.Id} SceneRouteId:{scene.RouteId} SceneType:{scene.SceneInfo.SceneType} EntityId {tEntity.Id} : Error {e}");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@@ -75,7 +75,7 @@ namespace TEngine.Demo
|
|||||||
private void OnConnectComplete()
|
private void OnConnectComplete()
|
||||||
{
|
{
|
||||||
IsConnect = true;
|
IsConnect = true;
|
||||||
Scene.Session.AddComponent<SessionHeartbeatComponent>().Start(15);
|
Scene.Session.AddComponent<SessionHeartbeatComponent>().Start(15000);
|
||||||
LogDebug("已连接到服务器");
|
LogDebug("已连接到服务器");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,8 +25,3 @@ catch (Exception e)
|
|||||||
{
|
{
|
||||||
Log.Error(e);
|
Log.Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3,10 +3,10 @@ package Sining.Message;
|
|||||||
/// Gate跟Map服务器进行通讯、注册Address协议
|
/// Gate跟Map服务器进行通讯、注册Address协议
|
||||||
message I_G2M_LoginAddressRequest // IRouteRequest,I_M2G_LoginAddressResponse
|
message I_G2M_LoginAddressRequest // IRouteRequest,I_M2G_LoginAddressResponse
|
||||||
{
|
{
|
||||||
long AddressId = 1; // 用来关联Address的Id,一般是账号Id或UnitId这些不会变动的
|
long AddressableId = 1; // 用来关联Address的Id,一般是账号Id或UnitId这些不会变动的
|
||||||
long GateRouteId = 2; // Gate的RouteIdId用于Map发送给客户端时需要
|
long GateRouteId = 2; // Gate的RouteIdId用于Map发送给客户端时需要
|
||||||
}
|
}
|
||||||
message I_M2G_LoginAddressResponse // IRouteResponse
|
message I_M2G_LoginAddressResponse // IRouteResponse
|
||||||
{
|
{
|
||||||
|
long AddressableId = 1;
|
||||||
}
|
}
|
@@ -17,7 +17,7 @@ namespace TEngine
|
|||||||
public uint OpCode() { return InnerOpcode.I_G2M_LoginAddressRequest; }
|
public uint OpCode() { return InnerOpcode.I_G2M_LoginAddressRequest; }
|
||||||
public long RouteTypeOpCode() { return CoreRouteType.Route; }
|
public long RouteTypeOpCode() { return CoreRouteType.Route; }
|
||||||
[ProtoMember(1)]
|
[ProtoMember(1)]
|
||||||
public long AddressId { get; set; }
|
public long AddressableId { get; set; }
|
||||||
[ProtoMember(2)]
|
[ProtoMember(2)]
|
||||||
public long GateRouteId { get; set; }
|
public long GateRouteId { get; set; }
|
||||||
}
|
}
|
||||||
@@ -27,5 +27,7 @@ namespace TEngine
|
|||||||
public uint OpCode() { return InnerOpcode.I_M2G_LoginAddressResponse; }
|
public uint OpCode() { return InnerOpcode.I_M2G_LoginAddressResponse; }
|
||||||
[ProtoMember(91, IsRequired = true)]
|
[ProtoMember(91, IsRequired = true)]
|
||||||
public uint ErrorCode { get; set; }
|
public uint ErrorCode { get; set; }
|
||||||
|
[ProtoMember(1)]
|
||||||
|
public long AddressableId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,14 +24,14 @@ public class H_C2G_LoginAddressRequestHandler : MessageRPC<H_C2G_LoginAddressReq
|
|||||||
// 1、首选分配一个可用、负载比较低的服务器给这个Unit、我这里就在ServerConfig.xsl表里拿一个MAP了、但实际开发过程可能比这个要复杂
|
// 1、首选分配一个可用、负载比较低的服务器给这个Unit、我这里就在ServerConfig.xsl表里拿一个MAP了、但实际开发过程可能比这个要复杂
|
||||||
// 我这里就简单些一个做为演示、其实这些逻辑开发者完全可以自己封装一个接口来做。
|
// 我这里就简单些一个做为演示、其实这些逻辑开发者完全可以自己封装一个接口来做。
|
||||||
// 在ServerConfig.xsl里找到MAP的进程、看到ID是3072通过这个Id在SceneConfig.xsl里找到对应的Scene的EntityId
|
// 在ServerConfig.xsl里找到MAP的进程、看到ID是3072通过这个Id在SceneConfig.xsl里找到对应的Scene的EntityId
|
||||||
var sceneEntityId = Helper.AddressableSceneHelper.GetSceneEntityIdByRouteId(3072);
|
var sceneEntityId = Helper.AddressableSceneHelper.GetSceneEntityId();
|
||||||
|
|
||||||
// 2、在InnerMessage里定义一个协议、用于Gate跟Map通讯的协议I_G2M_LoginAddress
|
// 2、在InnerMessage里定义一个协议、用于Gate跟Map通讯的协议I_G2M_LoginAddress
|
||||||
var loginAddressResponse = (I_M2G_LoginAddressResponse)await MessageHelper.CallInnerRoute(session.Scene,
|
var loginAddressResponse = (I_M2G_LoginAddressResponse)await MessageHelper.CallInnerRoute(session.Scene,
|
||||||
sceneEntityId,
|
sceneEntityId,
|
||||||
new I_G2M_LoginAddressRequest()
|
new I_G2M_LoginAddressRequest()
|
||||||
{
|
{
|
||||||
AddressId = session.Id,
|
AddressableId = session.Id,
|
||||||
GateRouteId = session.RuntimeId,
|
GateRouteId = session.RuntimeId,
|
||||||
});
|
});
|
||||||
if (loginAddressResponse.ErrorCode != 0)
|
if (loginAddressResponse.ErrorCode != 0)
|
||||||
@@ -40,7 +40,7 @@ public class H_C2G_LoginAddressRequestHandler : MessageRPC<H_C2G_LoginAddressReq
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 3、可寻址消息组件、挂载了这个组件可以接收和发送Addressable消息
|
// 3、可寻址消息组件、挂载了这个组件可以接收和发送Addressable消息
|
||||||
session.AddComponent<AddressableRouteComponent>();
|
session.AddComponent<AddressableRouteComponent>().SetAddressableId(loginAddressResponse.AddressableId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@@ -36,10 +36,10 @@ namespace TEngine.Logic
|
|||||||
// 一般这个信息是数据库里拿到或者其他服务器给传递过来了、这里主要演示怎么注册Address、所以这些步骤这里就不做了
|
// 一般这个信息是数据库里拿到或者其他服务器给传递过来了、这里主要演示怎么注册Address、所以这些步骤这里就不做了
|
||||||
// 这里我就模拟一个假的Unit数据使用
|
// 这里我就模拟一个假的Unit数据使用
|
||||||
// 1、首先创建一个Unit
|
// 1、首先创建一个Unit
|
||||||
var unit = AddressManage.Add(scene, request.AddressId, request.GateRouteId);
|
var unit = AddressManage.Add(scene, request.AddressableId, request.GateRouteId);
|
||||||
// 2、挂在AddressableMessageComponent组件、让这个Unit支持Address、并且会自动注册到网格中
|
// 2、挂在AddressableMessageComponent组件、让这个Unit支持Address、并且会自动注册到网格中
|
||||||
await unit.AddComponent<AddressableMessageComponent>().Register();
|
await unit.AddComponent<AddressableMessageComponent>().Register();
|
||||||
await FTask.CompletedTask;
|
response.AddressableId = unit.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,10 +33,10 @@ public static class AddressableSceneHelper
|
|||||||
return sceneEntityId;
|
return sceneEntityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long GetSceneEntityIdByRouteId(uint routeId)
|
public static long GetSceneEntityIdBySceneId(uint sceneId)
|
||||||
{
|
{
|
||||||
var sceneEntityId = 0L;
|
var sceneEntityId = 0L;
|
||||||
var sceneConfig = SceneConfigData.Instance.Get(routeId);
|
var sceneConfig = SceneConfigData.Instance.Get(sceneId);
|
||||||
sceneEntityId = sceneConfig.EntityId;
|
sceneEntityId = sceneConfig.EntityId;
|
||||||
return sceneEntityId;
|
return sceneEntityId;
|
||||||
}
|
}
|
||||||
|
35
DotNet/Logic/src/Helper/GameTickWatcher.cs
Normal file
35
DotNet/Logic/src/Helper/GameTickWatcher.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
namespace TEngine.Helper;
|
||||||
|
|
||||||
|
public class GameTickWatcher
|
||||||
|
{
|
||||||
|
private long m_startTick = 0;
|
||||||
|
|
||||||
|
public GameTickWatcher()
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
m_startTick = DateTime.Now.Ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算用时。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public float ElapseTime()
|
||||||
|
{
|
||||||
|
long endTick = DateTime.Now.Ticks;
|
||||||
|
return (endTick - m_startTick) / 10000f / 1000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算用时。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public void LogElapseTime(string tag)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"计算用时:{tag} 耗时 {this.ElapseTime()}");
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user