饭太稀
This commit is contained in:
50
Hotfix/CustomSystem/IRunSystem.cs
Normal file
50
Hotfix/CustomSystem/IRunSystem.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
// 这个是一个自定义系统类型,用于决定系统类型。
|
||||
// 也可以用枚举,看个人怎么使用了。
|
||||
public static class CustomSystemType
|
||||
{
|
||||
public const int RunSystem = 1;
|
||||
}
|
||||
// 这个是一个自定义系统,用于处理自定义事件。
|
||||
public abstract class RunSystem<T> : CustomSystem<T> where T : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义事件类型,用于决定事件的类型。
|
||||
/// </summary>
|
||||
public override int CustomEventType => CustomSystemType.RunSystem;
|
||||
/// <summary>
|
||||
/// 不知道为什么这样定义的,就照搬就可以了。
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
protected abstract override void Custom(T self);
|
||||
/// <summary>
|
||||
/// 不知道为什么这样定义的,就照搬就可以了。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override Type EntitiesType() => typeof(T);
|
||||
}
|
||||
// 下面是一个测试自定义系统。
|
||||
// 首先定义一个组件用来测试自定义系统。
|
||||
public class TestCustomSystemComponent : Entity
|
||||
{
|
||||
|
||||
}
|
||||
// 现在给TestCustomSystemComponent组件添加一个自定义系统。
|
||||
// 现在添加的就是上面定义的RunSystem自定义系统。
|
||||
public class TestCustomSystemComponentRunSystem : RunSystem<TestCustomSystemComponent>
|
||||
{
|
||||
protected override void Custom(TestCustomSystemComponent self)
|
||||
{
|
||||
Log.Debug($"执行了TestCustomSystemComponentRunSystem");
|
||||
}
|
||||
}
|
||||
// 执行方法
|
||||
// 在任何实体下获得Scene下面的EntityComponent.CustomSystem方法。
|
||||
// 比如下面这个
|
||||
// 第一个参数是你要执行自定义系统的实体实例
|
||||
// 第二个参数是自定义系统类型
|
||||
// scene.EntityComponent.CustomSystem(testCustomSystemComponent, CustomSystemType.RunSystem);
|
||||
// 你可以在OnCreateSceneEvent.cs的Handler方法里找到执行这个的例子。
|
||||
31
Hotfix/HTTPHandler/HelloController.cs
Normal file
31
Hotfix/HTTPHandler/HelloController.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Threading;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network.HTTP;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[ServiceFilter(typeof(SceneContextFilter))]
|
||||
public class HelloController : ControllerBase
|
||||
{
|
||||
private readonly Scene _scene;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数依赖注入
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
public HelloController(Scene scene)
|
||||
{
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
[HttpGet("greet")]
|
||||
public async FTask<IActionResult> Greet()
|
||||
{
|
||||
Log.Debug($"HelloController Thread.CurrentThread.ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
|
||||
return Ok($"Hello from the Fantasy controller! _scene.SceneType:{_scene.SceneType} _scene.SceneType:{_scene.SceneConfigId}");
|
||||
}
|
||||
}
|
||||
21
Hotfix/HTTPHandler/ProductsController.cs
Normal file
21
Hotfix/HTTPHandler/ProductsController.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ProductsController : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
public IActionResult MiniGame ([FromBody] Product product)
|
||||
{
|
||||
// 假设已经保存产品数据
|
||||
return Ok("Product created successfully");
|
||||
}
|
||||
}
|
||||
|
||||
public class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
45
Hotfix/HTTPHandler/UsersController.cs
Normal file
45
Hotfix/HTTPHandler/UsersController.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class UsersController : ControllerBase
|
||||
{
|
||||
private readonly Scene _scene;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数依赖注入
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
public UsersController(Scene scene)
|
||||
{
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
[HttpGet("{userId}")]
|
||||
public IActionResult GetUser(int userId)
|
||||
{
|
||||
return Ok($"User ID: {userId}");
|
||||
}
|
||||
|
||||
[HttpPost("register")]
|
||||
public IActionResult RegisterUser([FromBody] User user)
|
||||
{
|
||||
return Ok("User registered successfully");
|
||||
}
|
||||
|
||||
[HttpGet("greet")]
|
||||
public IActionResult Greet()
|
||||
{
|
||||
Log.Debug($"HelloController Thread.CurrentThread.ManagedThreadId:{Thread.CurrentThread.ManagedThreadId}");
|
||||
return Ok($"Hello from the Fantasy controller! _scene.SceneType:{_scene.SceneType} _scene.SceneType:{_scene.SceneConfigId}");
|
||||
}
|
||||
}
|
||||
|
||||
public class User
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
20
Hotfix/Hotfix.csproj
Normal file
20
Hotfix/Hotfix.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
|
||||
<LangVersion>default</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\Fantasy.Net\Fantasy.Net\Fantasy.Net.csproj" />
|
||||
<ProjectReference Include="..\Entity\Entity.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Benchmark\" />
|
||||
<Folder Include="Outer\NormalMessage\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
22
Hotfix/Inner/Addressable/G2M_RequestAddressableIdHandler.cs
Normal file
22
Hotfix/Inner/Addressable/G2M_RequestAddressableIdHandler.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class G2M_RequestAddressableIdHandler : RouteRPC<Scene, G2M_RequestAddressableId, M2G_ResponseAddressableId>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, G2M_RequestAddressableId request, M2G_ResponseAddressableId response, Action reply)
|
||||
{
|
||||
// 1、因为是测试代码,所以默认每次请求这个协议我都创建一个新的Unit来做Addressable。
|
||||
var unit = Entity.Create<Unit>(scene, false, true);
|
||||
// 2、给Unit添加AddressableMessageComponent组件,并执行Register(),向AddressableScene注册自己当前的位置。
|
||||
await unit.AddComponent<AddressableMessageComponent>().Register();
|
||||
// 3、返回给Gate服务器AddressableId
|
||||
response.AddressableId = unit.Id;
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
15
Hotfix/Inner/G2A_TestMessageHandler.cs
Normal file
15
Hotfix/Inner/G2A_TestMessageHandler.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class G2A_TestMessageHandler : Route<Scene,G2A_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(Scene entity, G2A_TestMessage message)
|
||||
{
|
||||
|
||||
|
||||
Log.Debug($"G2A_TestMessageHandler :{message.Tag}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
19
Hotfix/Inner/G2A_TestRequestHandler.cs
Normal file
19
Hotfix/Inner/G2A_TestRequestHandler.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class G2A_TestRequestHandler : RouteRPC<Scene, G2A_TestRequest, G2A_TestResponse>
|
||||
{
|
||||
private static int Count;
|
||||
protected override async FTask Run(Scene entity, G2A_TestRequest request, G2A_TestResponse response, Action reply)
|
||||
{
|
||||
if (++Count % 1000000 == 0)
|
||||
{
|
||||
Log.Debug($"count:1000000");
|
||||
}
|
||||
// Log.Debug($"{Count}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class G2Chat_CreateRouteRequestHandler : RouteRPC<Scene, G2Chat_CreateRouteRequest, Chat2G_CreateRouteResponse>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, G2Chat_CreateRouteRequest request, Chat2G_CreateRouteResponse response, Action reply)
|
||||
{
|
||||
// 接收到Gate消息后,首先建立一个实体用来后面接收Route消息。
|
||||
// 这里就拿ChatUnit来做这个。
|
||||
var chatUnit = Entity.Create<ChatUnit>(scene, true, true);
|
||||
// 把Gate传递过来的RouteId保存住,以便后面可以直接给Gate发送消息。
|
||||
// 例如断线等操作,都可以通过这个GateRouteId发送到Gate的Session上。
|
||||
chatUnit.GateRouteId = request.GateRouteId;
|
||||
// 把chatUnit的RunTimeId发送给Gate。
|
||||
// 正如之前所说任何实体的RunTimeId都可以当做RouteId使用。
|
||||
response.ChatRouteId = chatUnit.RouteId;
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
17
Hotfix/Inner/SubScene/G2M_CreateSubSceneRequestHandler.cs
Normal file
17
Hotfix/Inner/SubScene/G2M_CreateSubSceneRequestHandler.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class G2M_CreateSubSceneRequestHandler : RouteRPC<Scene, G2M_CreateSubSceneRequest, M2G_CreateSubSceneResponse>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, G2M_CreateSubSceneRequest request, M2G_CreateSubSceneResponse response, Action reply)
|
||||
{
|
||||
// 下面的SceneType传的是666,其实并没有这个类型,这个是我随便写的。
|
||||
var subScene = Scene.CreateSubScene(scene, 6666);
|
||||
// 返回subScene的运行时id
|
||||
response.SubSceneRouteId = subScene.RouteId;
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class G2SubScene_AddressableIdRequestHandler : RouteRPC<SubScene, G2SubScene_AddressableIdRequest, SubScene2G_AddressableIdResponse>
|
||||
{
|
||||
protected override async FTask Run(SubScene subScene, G2SubScene_AddressableIdRequest request, SubScene2G_AddressableIdResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"G2SubScene_AddressableIdRequestHandler {subScene.SceneType}");
|
||||
// 1、因为是测试代码,所以默认每次请求这个协议我都创建一个新的Unit来做Addressable。
|
||||
var unit = Entity.Create<Unit>(subScene, false, true);
|
||||
// 2、给Unit添加AddressableMessageComponent组件,并执行Register(),向AddressableScene注册自己当前的位置。
|
||||
await unit.AddComponent<AddressableMessageComponent>().Register();
|
||||
// 3、返回给Gate服务器AddressableId
|
||||
response.AddressableId = unit.Id;
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
13
Hotfix/Inner/SubScene/G2SubScene_SentMessageHandler.cs
Normal file
13
Hotfix/Inner/SubScene/G2SubScene_SentMessageHandler.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class G2SubScene_SentMessageHandler : Route<Scene, G2SubScene_SentMessage>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, G2SubScene_SentMessage message)
|
||||
{
|
||||
Log.Debug($"接受到来自Gate的消息 SceneType:{scene.SceneType} Message:{message.Tag}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
108
Hotfix/OnCreateSceneEvent.cs
Normal file
108
Hotfix/OnCreateSceneEvent.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Event;
|
||||
using Fantasy.Helper;
|
||||
using Fantasy.Serialize;
|
||||
using ProtoBuf;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class SubSceneTestComponent : Entity
|
||||
{
|
||||
public override void Dispose()
|
||||
{
|
||||
Log.Debug("销毁SubScene下的SubSceneTestComponent");
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class OnCreateSceneEvent : AsyncEventSystem<OnCreateScene>
|
||||
{
|
||||
private static long _addressableSceneRunTimeId;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the OnCreateScene event.
|
||||
/// </summary>
|
||||
/// <param name="self">The OnCreateScene object.</param>
|
||||
/// <returns>A task representing the asynchronous operation.</returns>
|
||||
protected override async FTask Handler(OnCreateScene self)
|
||||
{
|
||||
|
||||
// var epoch1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000;
|
||||
//
|
||||
// {
|
||||
// var now = TimeHelper.Transition(new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc));
|
||||
// var epochThisYear = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - epoch1970;
|
||||
// var time = (uint)((now - epochThisYear) / 1000);
|
||||
// Log.Debug($"time = {time} now = {now} epochThisYear = {epochThisYear}");
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// var now = TimeHelper.Transition(new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc));
|
||||
// var epochThisYear = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks / 10000 - epoch1970;
|
||||
// var time = (uint)((now - epochThisYear) / 1000);
|
||||
// Log.Debug($"time = {time} now = {now} epochThisYear = {epochThisYear}");
|
||||
// }
|
||||
|
||||
var scene = self.Scene;
|
||||
|
||||
switch (scene.SceneType)
|
||||
{
|
||||
case 6666:
|
||||
{
|
||||
var subSceneTestComponent = scene.AddComponent<SubSceneTestComponent>();
|
||||
Log.Debug("增加了SubSceneTestComponent");
|
||||
scene.EntityComponent.CustomSystem(subSceneTestComponent,CustomSystemType.RunSystem);
|
||||
break;
|
||||
}
|
||||
case SceneType.Addressable:
|
||||
{
|
||||
// scene.AddComponent<AddressableManageComponent>();
|
||||
_addressableSceneRunTimeId = scene.RuntimeId;
|
||||
break;
|
||||
}
|
||||
case SceneType.Map:
|
||||
{
|
||||
Log.Debug($"Map Scene SceneRuntimeId:{scene.RuntimeId}");
|
||||
break;
|
||||
}
|
||||
case SceneType.Chat:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case SceneType.Gate:
|
||||
{
|
||||
// var tasks = new List<FTask>(2000);
|
||||
// var session = scene.GetSession(_addressableSceneRunTimeId);
|
||||
// var sceneNetworkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
// var g2ATestRequest = new G2A_TestRequest();
|
||||
//
|
||||
// async FTask Call()
|
||||
// {
|
||||
// await sceneNetworkMessagingComponent.CallInnerRouteBySession(session,_addressableSceneRunTimeId,g2ATestRequest);
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < 100000000000; i++)
|
||||
// {
|
||||
// tasks.Clear();
|
||||
// for (int j = 0; j < tasks.Capacity; ++j)
|
||||
// {
|
||||
// tasks.Add(Call());
|
||||
// }
|
||||
// await FTask.WaitAll(tasks);
|
||||
// }
|
||||
|
||||
// 执行自定义系统
|
||||
var testCustomSystemComponent = scene.AddComponent<TestCustomSystemComponent>();
|
||||
scene.EntityComponent.CustomSystem(testCustomSystemComponent, CustomSystemType.RunSystem);
|
||||
// // 测试配置表
|
||||
// var instanceList = UnitConfigData.Instance.List;
|
||||
// var unitConfig = instanceList[0];
|
||||
// Log.Debug(instanceList[0].Dic[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_CreateAddressableRequestHandler : MessageRPC<C2G_CreateAddressableRequest, G2C_CreateAddressableResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_CreateAddressableRequest request, G2C_CreateAddressableResponse response, Action reply)
|
||||
{
|
||||
var scene = session.Scene;
|
||||
// 1、首先要通过SceneConfig配置文件拿到进行注册Addressable协议的服务器
|
||||
// 实际开发的时候,可能会根据一些规则来选择不同的Map服务器。
|
||||
// 演示的例子里只有一个MapScene,所以我就拿第一个Map服务器进行通讯了。
|
||||
// 我这里仅是演示功能,不是一定要这样拿Map
|
||||
var sceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[0];
|
||||
// 2、使用Scene.NetworkMessagingComponent.CallInnerRoute方法跟Gate服务器进行通讯。
|
||||
// CallInnerRoute方法跟Gate服务器进行通讯需要提供一个runTimeId,这个Id在sceneConfig.RouteId可以获取到。
|
||||
// 第二个参数是需要发送网络协议,这个协议在Fantasy/Examples/Config/ProtoBuf里的InnerBson或Inner文件定义。
|
||||
var responseAddressableId = (M2G_ResponseAddressableId)await scene.NetworkMessagingComponent.CallInnerRoute(sceneConfig.RouteId, new G2M_RequestAddressableId());
|
||||
// 3、给session添加一个AddressableRouteComponent组件,这个组件很重要、能否转发Addressable协议主要是通过这个。
|
||||
var addressableRouteComponent = session.AddComponent<AddressableRouteComponent>();
|
||||
// 4、拿到MapScene返回的AddressableId赋值给addressableRouteComponent.AddressableId。
|
||||
addressableRouteComponent.AddressableId = responseAddressableId.AddressableId;
|
||||
}
|
||||
}
|
||||
28
Hotfix/Outer/Addresable/C2G_SendAddressableToMapHandler.cs
Normal file
28
Hotfix/Outer/Addresable/C2G_SendAddressableToMapHandler.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
// ReSharper disable ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_SendAddressableToMapHandler : Message<C2G_SendAddressableToMap>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_SendAddressableToMap message)
|
||||
{
|
||||
var addressableRouteComponent = session.GetComponent<AddressableRouteComponent>();
|
||||
|
||||
if (addressableRouteComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Gate发送一个Addressable消息给MAP
|
||||
|
||||
await session.Scene.NetworkMessagingComponent.SendAddressable(addressableRouteComponent.AddressableId,
|
||||
new G2M_SendAddressableMessage()
|
||||
{
|
||||
Tag = message.Tag
|
||||
});
|
||||
}
|
||||
}
|
||||
40
Hotfix/Outer/Addresable/C2M_MoveToMapRequestHandler.cs
Normal file
40
Hotfix/Outer/Addresable/C2M_MoveToMapRequestHandler.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
using Fantasy.Platform.Net;
|
||||
using Fantasy.Serialize;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2M_MoveToMapRequestHandler : AddressableRPC<Unit, C2M_MoveToMapRequest, M2C_MoveToMapResponse>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, C2M_MoveToMapRequest request, M2C_MoveToMapResponse response, Action reply)
|
||||
{
|
||||
// 1、首先要通过SceneConfig配置文件拿到MapScene的配置文件。
|
||||
// 这里Map[1]就是要发送的服务器,因为Map[0]是当前的Scene。
|
||||
var scene = unit.Scene;
|
||||
var mapSceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[1];
|
||||
// 2、锁定Addressable防止在转移期间有消息发送过来。
|
||||
// LockAndRelease方法是先锁定Addressable消息后再销毁这个组件。
|
||||
// 注意:只有这个方法的销毁组件不会去Addressable里删除自己的位置信息。
|
||||
// 其他的任何销毁这个AddressableMessageComponent方法都会去Addressable里删除自己的位置信息。
|
||||
await unit.GetComponent<AddressableMessageComponent>().LockAndRelease();
|
||||
// 3、通过NetworkMessagingComponent发送内部消息给Map的Scene。
|
||||
var sendResponse = await scene.NetworkMessagingComponent.CallInnerRoute(mapSceneConfig.RouteId,
|
||||
new M2M_SendUnitRequest()
|
||||
{
|
||||
Unit = unit
|
||||
});
|
||||
if (sendResponse.ErrorCode != 0)
|
||||
{
|
||||
Log.Error($"转移Unit到目标Map服务器失败 ErrorCode={sendResponse.ErrorCode}");
|
||||
return;
|
||||
}
|
||||
// 这个Unit已经转移到另外的Map服务器了,所以就不需要这个组件了。
|
||||
unit.Dispose();
|
||||
Log.Debug("转移Unit到目标Map服务器成功");
|
||||
}
|
||||
}
|
||||
13
Hotfix/Outer/Addresable/C2M_TestMessageHandler.cs
Normal file
13
Hotfix/Outer/Addresable/C2M_TestMessageHandler.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2M_TestMessageHandler : Addressable<Unit, C2M_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, C2M_TestMessage message)
|
||||
{
|
||||
Log.Debug($"C2M_TestMessageHandler = {message.Tag} Scene:{unit.Scene.Scene.SceneConfigId}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
15
Hotfix/Outer/Addresable/C2M_TestRequestHandler.cs
Normal file
15
Hotfix/Outer/Addresable/C2M_TestRequestHandler.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2M_TestRequestHandler : AddressableRPC<Unit, C2M_TestRequest, M2C_TestResponse>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, C2M_TestRequest request, M2C_TestResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"Receive C2M_TestRequest Tag = {request.Tag}");
|
||||
response.Tag = "Hello M2C_TestResponse";
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
13
Hotfix/Outer/Addresable/G2M_SendAddressableMessageHandler.cs
Normal file
13
Hotfix/Outer/Addresable/G2M_SendAddressableMessageHandler.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class G2M_SendAddressableMessageHandler : Addressable<Unit, G2M_SendAddressableMessage>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, G2M_SendAddressableMessage message)
|
||||
{
|
||||
Log.Debug($"收到Gate发送来的Addressable消息 message:{message.Tag}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
21
Hotfix/Outer/Addresable/M2M_SendUnitRequestHandler.cs
Normal file
21
Hotfix/Outer/Addresable/M2M_SendUnitRequestHandler.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class M2M_SendUnitRequestHandler : RouteRPC<Scene, M2M_SendUnitRequest, M2M_SendUnitResponse>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, M2M_SendUnitRequest request, M2M_SendUnitResponse response, Action reply)
|
||||
{
|
||||
var requestUnit = request.Unit;
|
||||
// 反序列化Unit,把Unit注册到框架中
|
||||
requestUnit.Deserialize(scene);
|
||||
// 解锁这个Unit的Addressable消息,解锁后,Gate上缓存的消息会发送到这里。
|
||||
// 由于AddressableMessageComponent不支持存数据库,所以在发送Unit的时候,会自动把这个给忽略掉。
|
||||
// 所以需要再次手动的添加下才可以。
|
||||
await requestUnit.AddComponent<AddressableMessageComponent>().UnLock("M2M_SendUnitRequestHandler");
|
||||
Log.Debug($"传送完成 {scene.SceneConfigId}");
|
||||
}
|
||||
}
|
||||
16
Hotfix/Outer/NormalMessage/Gate/C2G_TestMessageHandler.cs
Normal file
16
Hotfix/Outer/NormalMessage/Gate/C2G_TestMessageHandler.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy.Gate;
|
||||
|
||||
public sealed class C2G_TestMessageHandler : Message<C2G_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_TestMessage message)
|
||||
{
|
||||
Log.Debug($"Receive C2G_TestMessage Tag={message.Tag}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
16
Hotfix/Outer/NormalMessage/Gate/C2G_TestRequestHandler.cs
Normal file
16
Hotfix/Outer/NormalMessage/Gate/C2G_TestRequestHandler.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy.Gate;
|
||||
|
||||
public sealed class C2G_TestRequestHandler : MessageRPC<C2G_TestRequest, G2C_TestResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_TestRequest request, G2C_TestResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"Receive C2G_TestRequest Tag = {request.Tag}");
|
||||
response.Tag = "Hello G2C_TestResponse";
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy.Gate;
|
||||
|
||||
public sealed class C2G_TestRequestPushMessageHandler : Message<C2G_TestRequestPushMessage>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_TestRequestPushMessage message)
|
||||
{
|
||||
// 因为没有服务器的相关的逻辑,所以制作了一个协议来触发服务器发送消息给客户端的环境。
|
||||
// 使用当前会话的Session.Send发送消息给客户端。
|
||||
// 如果需要群发,你可以用一个容器保存起来,发送的时候遍历这个容器调用Send方法就可以了。
|
||||
session.Send(new G2C_PushMessage()
|
||||
{
|
||||
Tag = "Hi G2C_PushMessage"
|
||||
});
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2Chat_TestRPCRoamingRequestHandler : RoamingRPC<Terminus, C2Chat_TestRPCRoamingRequest, Chat2C_TestRPCRoamingResponse>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Chat_TestRPCRoamingRequest request, Chat2C_TestRPCRoamingResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"C2Chat_TestRPCRoamingRequestHandler message:{request.Tag} SceneType:{terminus.Scene.SceneType} SceneId:{terminus.Scene.RuntimeId}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Chat_TestRoamingMessageHandler : Roaming<Terminus, C2Chat_TestRoamingMessage>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Chat_TestRoamingMessage message)
|
||||
{
|
||||
Log.Debug($"C2Chat_TestRoamingMessageHandler message:{message.Tag} SceneType:{terminus.Scene.SceneType} SceneId:{terminus.Scene.RuntimeId}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Chat_TestSendMapMessageHandler : Roaming<Terminus, C2Chat_TestSendMapMessage>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Chat_TestSendMapMessage message)
|
||||
{
|
||||
terminus.Send(RoamingType.MapRoamingType, new Chat2M_TestMessage()
|
||||
{
|
||||
Tag = "Hi Inner Roaming Message!"
|
||||
});
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Platform.Net;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_ConnectRoamingRequestHandler : MessageRPC<C2G_ConnectRoamingRequest, G2C_ConnectRoamingResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_ConnectRoamingRequest request, G2C_ConnectRoamingResponse response, Action reply)
|
||||
{
|
||||
// 给session创建一个漫游功能。
|
||||
// 这个功能很重要,这个组件是整个Roaming系统最核心的组件,这个组件会处理Roaming协议
|
||||
// 这个功能会处理Roaming协议,所以创建这个是必须的。
|
||||
// CreateRoaming需要支持三个参数:
|
||||
// roamingId:这个参数是RoamingId,RoamingId是Roaming的唯一标识,不能重复。
|
||||
// 指定了这个RoamingId后,服务器其他漫游终端的Id会是你设置的RoamingId。
|
||||
// 这样操作方便统一管理漫游协议。
|
||||
// 一般这个RoamingId是一个角色的Id,这样方便管理。
|
||||
// isAutoDispose:是否在Session断开的时候自动断开漫游功能。
|
||||
// delayRemove:如果开启了自定断开漫游功能需要设置一个延迟多久执行断开。
|
||||
// 这里没有角色的Id,所以这里使用1来代替。
|
||||
// isAutoDispose我选择自动断开,这个断开的时机是Session断开后执行。
|
||||
// delayRemove断开漫游功能后,Session会自动断开,所以这里设置延迟1000毫秒执行断开。
|
||||
// 这里创建的漫游功能会自动处理Roaming协议,所以不需要手动处理Roaming协议。
|
||||
var roaming = session.CreateRoaming(1,true,1000);
|
||||
// 通过SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[0]拿到Map场景的配置信息
|
||||
// 如果需要协议漫游其他Scene可以在配置中查找要漫游的服务器。
|
||||
// 可以同时漫游多个Scene,但每个Scene的漫游都有一个固定的类型,不能重复。
|
||||
var mapConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[0];
|
||||
// 通过RoamingComponent.Link(session, mapConfig, 1, 1)链接Map场景
|
||||
// 第一个参数是Session,第二个参数是Map场景的配置信息,第三个参数是Map场景的RouteId,第四个参数是Map场景的RoamingType。
|
||||
// 这个RoamingType是通过RoamingType.Config文件中定义的。
|
||||
// RouteType.Config文件位置在你定义的网络文件协议文件夹下。如果找不到RoamingType.Config文件,可以运行下导出协议工具导出一个协议后会自动创建。
|
||||
// 该示例工程下文件位置在Config/NetworkProtocol/RoamingType.Config
|
||||
// 执行完后漫游会自动把Session绑定到Map场景上。
|
||||
// 后面发送该类型的消息到Session上会自动转发给Map场景。
|
||||
var linkResponse = await roaming.Link(session, mapConfig, RoamingType.MapRoamingType);
|
||||
if (linkResponse != 0)
|
||||
{
|
||||
response.ErrorCode = linkResponse;
|
||||
return;
|
||||
}
|
||||
// 同样,你可以创建多个漫游的场景,但每个场景的RouteId和RoamingType不能重复。
|
||||
// 这里创建Chat场景的漫游。
|
||||
var chatConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Chat)[0];
|
||||
linkResponse = await roaming.Link(session, chatConfig, RoamingType.ChatRoamingType);
|
||||
if (linkResponse != 0)
|
||||
{
|
||||
response.ErrorCode = linkResponse;
|
||||
return;
|
||||
}
|
||||
// 如果你觉的每次创建一个场景的漫游都麻烦,你可以利用RoamingType.RoamingTypes遍历创建。
|
||||
// 但这样的会把你在RoamingType.Config定义的都创建出来
|
||||
foreach (var roamingType in RoamingType.RoamingTypes)
|
||||
{
|
||||
// 这里添加roaming.Link的方法进行创建。
|
||||
}
|
||||
}
|
||||
}
|
||||
17
Hotfix/Outer/Roaming/Map/C2Map_PushMessageToClientHandler.cs
Normal file
17
Hotfix/Outer/Roaming/Map/C2Map_PushMessageToClientHandler.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Map_PushMessageToClientHandler : Roaming<Terminus, C2Map_PushMessageToClient>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Map_PushMessageToClient message)
|
||||
{
|
||||
terminus.Send(new Map2C_PushMessageToClient()
|
||||
{
|
||||
Tag = message.Tag
|
||||
});
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
15
Hotfix/Outer/Roaming/Map/C2Map_TestRoamingMessageHandler.cs
Normal file
15
Hotfix/Outer/Roaming/Map/C2Map_TestRoamingMessageHandler.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2Map_TestRoamingMessageHandler : Roaming<Terminus, C2Map_TestRoamingMessage>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Map_TestRoamingMessage message)
|
||||
{
|
||||
Log.Debug($"C2Map_TestRoamingMessageHandler message:{message.Tag} SceneType:{terminus.Scene.SceneType} SceneId:{terminus.Scene.RuntimeId}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
17
Hotfix/Outer/Roaming/Map/C2Map_TestTransferRequestHandler.cs
Normal file
17
Hotfix/Outer/Roaming/Map/C2Map_TestTransferRequestHandler.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Platform.Net;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2Map_TestTransferRequestHandler : RoamingRPC<Terminus, C2Map_TestTransferRequest, Map2C_TestTransferResponse>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, C2Map_TestTransferRequest request, Map2C_TestTransferResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"C2Map_TestTransferRequestHandler1 terminus:{terminus.RuntimeId}");
|
||||
var mapConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[1];
|
||||
response.ErrorCode = await terminus.StartTransfer(mapConfig.RouteId);
|
||||
}
|
||||
}
|
||||
15
Hotfix/Outer/Roaming/Map/Chat2M_TestMessageHandler.cs
Normal file
15
Hotfix/Outer/Roaming/Map/Chat2M_TestMessageHandler.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Roaming;
|
||||
using Fantasy.Roaming;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class Chat2M_TestMessageHandler : Roaming<Terminus, Chat2M_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(Terminus terminus, Chat2M_TestMessage message)
|
||||
{
|
||||
Log.Debug($"Chat2M_TestMessageHandler message:{message.Tag} SceneType:{terminus.Scene.SceneType} SceneId:{terminus.Scene.RuntimeId}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
13
Hotfix/Outer/RouteMessage/C2Chat_TestMessageHandler.cs
Normal file
13
Hotfix/Outer/RouteMessage/C2Chat_TestMessageHandler.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Chat_TestMessageHandler : Route<ChatUnit, C2Chat_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(ChatUnit entity, C2Chat_TestMessage message)
|
||||
{
|
||||
Log.Debug($"C2Chat_TestMessageHandler.c2Chat_TestMessage: {message}");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Chat_TestMessageRequestHandler : RouteRPC<ChatUnit, C2Chat_TestMessageRequest, Chat2C_TestMessageResponse>
|
||||
{
|
||||
protected override async FTask Run(ChatUnit entity, C2Chat_TestMessageRequest request, Chat2C_TestMessageResponse response, Action reply)
|
||||
{
|
||||
Log.Debug($"C2Chat_TestMessageRequestHandler request = {request}");
|
||||
response.Tag = "Hello RouteRPC";
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2Chat_TestRequestPushMessageHandler : Route<ChatUnit, C2Chat_TestRequestPushMessage>
|
||||
{
|
||||
protected override async FTask Run(ChatUnit chatUnit, C2Chat_TestRequestPushMessage message)
|
||||
{
|
||||
// 因为没有服务器的相关的逻辑,所以制作了一个协议来触发服务器发送消息给客户端的环境。
|
||||
// 使用当前Scene.NetworkMessagingComponent.SendInnerRoute发送消息给客户端。
|
||||
// 只需要把消息发送给创建链接的Gate上就会自动转发消息到客户端上。
|
||||
// 因为chatUnit.GateRouteId是在G2Chat_CreateRouteRequestHandler方法里记录的所以直接使用这个就可以了。
|
||||
|
||||
chatUnit.Scene.NetworkMessagingComponent.SendInnerRoute(chatUnit.GateRouteId, new Chat2C_PushMessage()
|
||||
{
|
||||
Tag = "Hi Route Chat2C_PushMessage"
|
||||
});
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_CreateChatRouteRequestHandler : MessageRPC<C2G_CreateChatRouteRequest, G2C_CreateChatRouteResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_CreateChatRouteRequest request, G2C_CreateChatRouteResponse response, Action reply)
|
||||
{
|
||||
// 首先需要找到一个需要建立Route的Scene的SceneConfig。
|
||||
// 例子演示的连接的ChatScene,所以这里我通过SceneConfigData拿到这个SceneConfig。
|
||||
// 如果是其他Scene,用法跟这个没有任何区别。
|
||||
var chatSceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Chat)[0];
|
||||
// 通过chatSceneConfig拿到这个Scene的RouteId
|
||||
var chatRouteId = chatSceneConfig.RouteId;
|
||||
// 通过Scene拿到当前Scene的NetworkMessagingComponent。
|
||||
// NetworkMessagingComponent是服务器之间通讯的唯一手段。
|
||||
var networkMessagingComponent = session.Scene.NetworkMessagingComponent;
|
||||
// 通过CallInnerRoute方法发送一个RPC消息给ChatScene上。
|
||||
// 任何一个实体的RunTimeId都可以做为RouteId使用。
|
||||
// 所以这个传递了一个session.RunTimeId,是方便Chat发送消息回Gate上。
|
||||
var routeResponse = (Chat2G_CreateRouteResponse)await networkMessagingComponent.CallInnerRoute(chatRouteId,
|
||||
new G2Chat_CreateRouteRequest()
|
||||
{
|
||||
GateRouteId = session.RouteId
|
||||
});
|
||||
if (routeResponse.ErrorCode != 0)
|
||||
{
|
||||
// 如果ErrorCode不是0表示请求的协议发生错误,应该提示给客户端。
|
||||
// 这里就不做这个了。
|
||||
return;
|
||||
}
|
||||
// 要实现Route协议的转发,需要给Session添加一个RouteComponent,这个非常重要。
|
||||
var routeComponent = session.AddComponent<RouteComponent>();
|
||||
// 需要再Examples/Config/NetworkProtocol/RouteType.Config里添加一个ChatRoute
|
||||
// 然后点击导表工具,会自动生成一个RouteType.cs文件。
|
||||
// 使用你定义的ChatRoute当routeType的参数传递进去。
|
||||
// routeResponse会返回一个ChatRouteId,这个就是Chat的RouteId。
|
||||
routeComponent.AddAddress((int)RouteType.ChatRoute,routeResponse.ChatRouteId);
|
||||
// 这些操作完成后,就完成了Route消息的建立。
|
||||
// 后面可以直接发送Route消息通过Gate自动中转给Chat了。
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Network.Route;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_CreateSubSceneAddressableRequestHandler : MessageRPC<C2G_CreateSubSceneAddressableRequest, G2C_CreateSubSceneAddressableResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_CreateSubSceneAddressableRequest request, G2C_CreateSubSceneAddressableResponse response, Action reply)
|
||||
{
|
||||
var scene = session.Scene;
|
||||
var subSceneRouteId = session.GetComponent<GateSubSceneFlagComponent>().SubSceneRouteId;
|
||||
// 1、向SubScene请求AddressableId
|
||||
var responseAddressableId = (SubScene2G_AddressableIdResponse)await scene.NetworkMessagingComponent.CallInnerRoute(subSceneRouteId, new G2SubScene_AddressableIdRequest());
|
||||
// 2、给session添加一个AddressableRouteComponent组件,这个组件很重要、能否转发Addressable协议主要是通过这个。
|
||||
var addressableRouteComponent = session.AddComponent<AddressableRouteComponent>();
|
||||
// 3、拿到SubScene返回的AddressableId赋值给addressableRouteComponent.AddressableId。
|
||||
addressableRouteComponent.AddressableId = responseAddressableId.AddressableId;
|
||||
}
|
||||
}
|
||||
26
Hotfix/Outer/SubScene/C2G_CreateSubSceneRequestHandler.cs
Normal file
26
Hotfix/Outer/SubScene/C2G_CreateSubSceneRequestHandler.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using Fantasy.Platform.Net;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public sealed class C2G_CreateSubSceneRequestHandler : MessageRPC<C2G_CreateSubSceneRequest, G2C_CreateSubSceneResponse>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_CreateSubSceneRequest request, G2C_CreateSubSceneResponse response, Action reply)
|
||||
{
|
||||
var scene = session.Scene;
|
||||
var sceneConfig = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Map)[0];
|
||||
var createSubSceneResponse = (M2G_CreateSubSceneResponse)await scene.NetworkMessagingComponent.CallInnerRoute(sceneConfig.RouteId, new G2M_CreateSubSceneRequest());
|
||||
|
||||
if (createSubSceneResponse.ErrorCode != 0)
|
||||
{
|
||||
// 创建SubScene失败。
|
||||
response.ErrorCode = createSubSceneResponse.ErrorCode;
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录下这个RouteId,以便后续的消息转发。
|
||||
session.AddComponent<GateSubSceneFlagComponent>().SubSceneRouteId = createSubSceneResponse.SubSceneRouteId;
|
||||
}
|
||||
}
|
||||
18
Hotfix/Outer/SubScene/C2G_SendToSubSceneMessageHandler.cs
Normal file
18
Hotfix/Outer/SubScene/C2G_SendToSubSceneMessageHandler.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2G_SendToSubSceneMessageHandler : Message<C2G_SendToSubSceneMessage>
|
||||
{
|
||||
protected override async FTask Run(Session session, C2G_SendToSubSceneMessage message)
|
||||
{
|
||||
var subSceneRouteId = session.GetComponent<GateSubSceneFlagComponent>().SubSceneRouteId;
|
||||
session.Scene.NetworkMessagingComponent.SendInnerRoute(subSceneRouteId, new G2SubScene_SentMessage()
|
||||
{
|
||||
Tag = "Hi SubScene",
|
||||
});
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2SubScene_TestDisposeMessageHandler : Addressable<Unit, C2SubScene_TestDisposeMessage>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, C2SubScene_TestDisposeMessage message)
|
||||
{
|
||||
var unitScene = unit.Scene;
|
||||
var unitSceneSceneType = unitScene.SceneType;
|
||||
unitScene.Dispose();
|
||||
Log.Debug($"{unitSceneSceneType} {unitScene.RuntimeId} is Dispose!");
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
14
Hotfix/Outer/SubScene/C2SubScene_TestMessageHandler.cs
Normal file
14
Hotfix/Outer/SubScene/C2SubScene_TestMessageHandler.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace Fantasy;
|
||||
|
||||
public class C2SubScene_TestMessageHandler : Addressable<Unit, C2SubScene_TestMessage>
|
||||
{
|
||||
protected override async FTask Run(Unit unit, C2SubScene_TestMessage message)
|
||||
{
|
||||
Log.Debug($"C2M_TestMessageHandler = {message.Tag} SceneType:{unit.Scene.SceneType} {unit.Scene.GetComponent<SubSceneTestComponent>() == null}");
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user