饭太稀
This commit is contained in:
@@ -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