完成离线消息发送和上线获取离线消息
This commit is contained in:
@@ -21,6 +21,7 @@ public class
|
||||
}
|
||||
|
||||
var channel = await channelCenter.Create(entity);
|
||||
|
||||
|
||||
response.ChannelId = channel.Id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public class
|
||||
C2Chat_GetOfflineMessageRequestHandler : RouteRPC<ChatUnit, C2Chat_GetOfflineMessageRequest,
|
||||
Caht2C_GetOfflineMessageResponse>
|
||||
{
|
||||
protected override async FTask Run(ChatUnit entity, C2Chat_GetOfflineMessageRequest request,
|
||||
Caht2C_GetOfflineMessageResponse response,
|
||||
Action reply)
|
||||
{
|
||||
var chatUnitManage = entity.Scene.GetComponent<ChatUnitManageComponent>();
|
||||
if (chatUnitManage.NotSendMessage.TryGetValue(entity.Id, out var list))
|
||||
{
|
||||
response.Message.AddRange(list);
|
||||
chatUnitManage.NotSendMessage.RemoveByKey(entity.Id);
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,11 @@ public class
|
||||
protected override async FTask Run(ChatUnit entity, C2Chat_JoinChannelRequest request,
|
||||
Caht2C_JoinChannelResponse response, Action reply)
|
||||
{
|
||||
if (request.Target < 1)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrArgs;
|
||||
return;
|
||||
}
|
||||
var channelCenter = entity.Scene.GetComponent<ChatChannelCenterComponent>();
|
||||
if (channelCenter == null)
|
||||
{
|
||||
|
||||
@@ -11,18 +11,35 @@ public sealed class
|
||||
protected override async FTask Run(ChatUnit chatUnit, C2Chat_SendMessageRequest request,
|
||||
Caht2C_SendMessageResponse response, Action reply)
|
||||
{
|
||||
if (request.Target < 1)
|
||||
{
|
||||
response.ErrorCode = ErrorCode.ErrArgs;
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.Type == 0) //频道聊天
|
||||
{
|
||||
|
||||
ChatSceneHelper.BroadcastChannel(chatUnit.Scene, request.Target, new ChatMessageInfo()
|
||||
{
|
||||
Content = request.Message,
|
||||
});
|
||||
}
|
||||
else if (request.Type == 1) //私聊
|
||||
{
|
||||
|
||||
//发送私聊
|
||||
ChatSceneHelper.PrivateMessage(chatUnit.Scene, chatUnit.Id, request.Target, new ChatMessageInfo()
|
||||
{
|
||||
Content = request.Message,
|
||||
});
|
||||
}
|
||||
ChatSceneHelper.Broadcast(chatUnit.Scene, new ChatMessageInfo()
|
||||
else if (request.Type == 3) //广播聊天
|
||||
{
|
||||
Content = request.Message,
|
||||
});
|
||||
ChatSceneHelper.BroadcastAll(chatUnit.Scene, new ChatMessageInfo()
|
||||
{
|
||||
Content = request.Message,
|
||||
});
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,11 @@ public class G2Chat_EnterRequestHandler : RouteRPC<Scene, G2Chat_EnterRequest, C
|
||||
{
|
||||
var roleId = request.Role.RoleId;
|
||||
Log.Debug($"收到 G2Chat_EnterRequestHandler {roleId}");
|
||||
|
||||
|
||||
|
||||
// 在缓存中检查该账号是否存在
|
||||
var chatUnitManageComponent = scene.GetComponent<ChatUnitManageComponent>();
|
||||
var account = await chatUnitManageComponent.Online(scene, request.Role, request.GateRouteId);
|
||||
|
||||
response.RoleRouteId = account.RuntimeId;
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
16
Hotfix/Chat/Handler/Inner/G2Chat_ExitRequestHandler.cs
Normal file
16
Hotfix/Chat/Handler/Inner/G2Chat_ExitRequestHandler.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network.Interface;
|
||||
|
||||
namespace NB.Chat;
|
||||
|
||||
public class G2Chat_ExitRequestHandler : RouteRPC<Scene, G2Chat_ExitRequest, Chat2G_ExitResponse>
|
||||
{
|
||||
protected override async FTask Run(Scene scene, G2Chat_ExitRequest request, Chat2G_ExitResponse response,
|
||||
Action reply)
|
||||
{
|
||||
// 在缓存中检查该账号是否存在
|
||||
var chatUnitManageComponent = scene.GetComponent<ChatUnitManageComponent>();
|
||||
await chatUnitManageComponent.Offline(scene, request.AccountId, request.GateRouteId);
|
||||
}
|
||||
}
|
||||
@@ -8,22 +8,107 @@ public static class ChatSceneHelper
|
||||
{
|
||||
#region 消息发送
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条私聊
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="selfId"></param>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void PrivateMessage(Scene scene, long selfId, long targetId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
var chatUnit = chatUnitManage.Get(targetId);
|
||||
message.Type = 1;
|
||||
message.Source = selfId;
|
||||
if (chatUnit != null)
|
||||
{
|
||||
//对方在线
|
||||
BroadcastAll(scene, message, [targetId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//对方不在线,存入待领取列表,等待玩家下次登录领取
|
||||
chatUnitManage.SaveOfflineMessage(targetId, message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条地图消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="mapId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void BroadcastMap(Scene scene, long mapId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
HashSet<long> targets = new HashSet<long>();
|
||||
foreach (var (_, chatUnit) in chatUnitManage.ChatUnits)
|
||||
{
|
||||
if (chatUnit.MapId == mapId)
|
||||
{
|
||||
targets.Add(chatUnit.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.Count < 1)
|
||||
{
|
||||
Log.Info("地图在线人数为0,群发取消");
|
||||
return;
|
||||
}
|
||||
|
||||
BroadcastAll(scene, message, targets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送一条频道消息
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="channelId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void BroadcastChannel(Scene scene, long channelId, ChatMessageInfo message)
|
||||
{
|
||||
var chatUnitManage = scene.GetComponent<ChatUnitManageComponent>();
|
||||
if (chatUnitManage == null) return;
|
||||
HashSet<long> targets = new HashSet<long>();
|
||||
foreach (var (_, chatUnit) in chatUnitManage.ChatUnits)
|
||||
{
|
||||
if (chatUnit.CurrentChannel == channelId)
|
||||
{
|
||||
targets.Add(chatUnit.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (targets.Count < 1)
|
||||
{
|
||||
Log.Info("频道在线人数为0,群发取消");
|
||||
return;
|
||||
}
|
||||
|
||||
BroadcastAll(scene, message, targets);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 广播消息给所有人
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void Broadcast(Scene scene, ChatMessageInfo message)
|
||||
/// <param name="targets"></param>
|
||||
public static void BroadcastAll(Scene scene, ChatMessageInfo message, HashSet<long>? targets = null)
|
||||
{
|
||||
Log.Info("广播消息===");
|
||||
//发送给所有Gate服务器,让Gate转发给其他客户端
|
||||
var gateConfigs = SceneConfigData.Instance.GetSceneBySceneType(SceneType.Gate);
|
||||
var sendMessage = new Chat2G_ChatMessage()
|
||||
{
|
||||
Message = message
|
||||
Message = message,
|
||||
};
|
||||
if (targets != null && targets.Count > 0)
|
||||
{
|
||||
sendMessage.IdList.AddRange(targets);
|
||||
}
|
||||
|
||||
var networkMessagingComponent = scene.NetworkMessagingComponent;
|
||||
foreach (var config in gateConfigs)
|
||||
{
|
||||
@@ -37,7 +122,7 @@ public static class ChatSceneHelper
|
||||
|
||||
#region 上线下线
|
||||
|
||||
public static async FTask<long> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId)
|
||||
public static async FTask<(long, long)> Online(Scene scene, RoleSimpleInfo roleSimple, long gateRuntimeId)
|
||||
{
|
||||
var gameSceneConfig = GetSceneConfig();
|
||||
var gameRouteId = gameSceneConfig.RouteId;
|
||||
@@ -51,10 +136,30 @@ public static class ChatSceneHelper
|
||||
|
||||
if (gameResponse.ErrorCode != 0)
|
||||
{
|
||||
return 0;
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
return gameResponse.RoleRouteId;
|
||||
return (gameResponse.RoleRouteId, gameRouteId);
|
||||
// return gameRouteId;
|
||||
}
|
||||
|
||||
public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId, long sceneRouteId)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var gameResponse = (Chat2G_ExitResponse)await scene.NetworkMessagingComponent.CallInnerRoute(
|
||||
sceneRouteId, new G2Chat_ExitRequest()
|
||||
{
|
||||
AccountId = accountId,
|
||||
GateRouteId = gateRuntimeId
|
||||
});
|
||||
if (gameResponse.ErrorCode == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log.Error("重试多次还是退出失败,需检查");
|
||||
}
|
||||
|
||||
private static SceneConfig GetSceneConfig()
|
||||
|
||||
@@ -37,7 +37,11 @@ public static class ChatChannelCenterComponentSystem
|
||||
|
||||
//查数据库
|
||||
channel = await self.Scene.World.DataBase.Query<ChatChannel>(channelId, true);
|
||||
self.Channels.Add(channel.Id, channel);
|
||||
if (channel != null)
|
||||
{
|
||||
self.Channels.Add(channel.Id, channel);
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,21 @@ namespace NB.Chat;
|
||||
|
||||
public static class ChatUnitManageComponentSystem
|
||||
{
|
||||
#region 消息缓存
|
||||
|
||||
/// <summary>
|
||||
/// 离线消息,进入待领取队列
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="targetId"></param>
|
||||
/// <param name="message"></param>
|
||||
public static void SaveOfflineMessage(this ChatUnitManageComponent self, long targetId, ChatMessageInfo message)
|
||||
{
|
||||
self.NotSendMessage.Add(targetId, message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 上线下线
|
||||
|
||||
/// <summary>
|
||||
@@ -15,7 +30,8 @@ public static class ChatUnitManageComponentSystem
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="roleSimpleInfo"></param>
|
||||
/// <param name="gateRouteId"></param>
|
||||
public static async FTask<ChatUnit?> Online(this ChatUnitManageComponent self, Scene scene, RoleSimpleInfo roleSimpleInfo,
|
||||
public static async FTask<ChatUnit?> Online(this ChatUnitManageComponent self, Scene scene,
|
||||
RoleSimpleInfo roleSimpleInfo,
|
||||
long gateRouteId)
|
||||
{
|
||||
var accountId = roleSimpleInfo.RoleId;
|
||||
@@ -30,14 +46,22 @@ public static class ChatUnitManageComponentSystem
|
||||
account.GateRouteId = gateRouteId;
|
||||
account.Role = roleSimpleInfo;
|
||||
}
|
||||
|
||||
|
||||
await FTask.CompletedTask;
|
||||
return account;
|
||||
}
|
||||
|
||||
public static async FTask Offline(this ChatUnitManageComponent self, Scene scene, long accountId)
|
||||
public static async FTask Offline(this ChatUnitManageComponent self, Scene scene, long accountId, long gateRouteId)
|
||||
{
|
||||
self.Remove(accountId);
|
||||
if (self.TryGet(accountId, out var unit) && unit != null)
|
||||
{
|
||||
if (unit.GateRouteId == gateRouteId)
|
||||
{
|
||||
Log.Info("退出当前聊天服==");
|
||||
self.Remove(accountId); //如果当前网关和下线的网关一致
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,4 +34,8 @@ public static class GameSceneHelper
|
||||
|
||||
return (gameResponse.RoleRouteId, gameResponse.RoleInfo);
|
||||
}
|
||||
|
||||
public static async FTask Offline(Scene scene, long accountId, long gateRuntimeId)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,34 @@ public class Chat2G_ChatMessageHandler : Route<Scene, Chat2G_ChatMessage>
|
||||
{
|
||||
Message = message.Message,
|
||||
};
|
||||
|
||||
var idList = message.IdList;
|
||||
bool isAll = !(idList != null && idList.Count > 0);
|
||||
|
||||
var gateUnitManage = scene.GetComponent<GateUnitManageComponent>();
|
||||
|
||||
foreach (var session in gateUnitManage.ForEachUnitSession())
|
||||
if (isAll)
|
||||
{
|
||||
session.Send(chatMessage);
|
||||
foreach (var session in gateUnitManage.ForEachUnitSession())
|
||||
{
|
||||
session.Send(chatMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idList == null) return;
|
||||
foreach (var (_, gateUnit) in gateUnitManage.Units)
|
||||
{
|
||||
if (gateUnit.AccountID > 0 && idList.Contains(gateUnit.AccountID))
|
||||
{
|
||||
Session session = gateUnit.Session;
|
||||
if (session != null)
|
||||
{
|
||||
session.Send(chatMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
|
||||
// 在缓存中检查该账号是否存在
|
||||
var gateUnitManageComponent = scene.GetComponent<GateUnitManageComponent>();
|
||||
|
||||
if (!gateUnitManageComponent.TryGet(accountId, out var gateUnit))
|
||||
{
|
||||
gateUnit = gateUnitManageComponent.Add(session, accountId);
|
||||
}
|
||||
|
||||
var gateUnit = gateUnitManageComponent.Online(session, accountId);
|
||||
|
||||
if (gateUnit == null)
|
||||
{
|
||||
@@ -40,11 +38,11 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
|
||||
session.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
response.ErrorCode = await GateLoginHelper.Online(gateUnit);
|
||||
Log.Debug($"当前的Gate服务器:{session.Scene.SceneConfigId} accountId:{accountId}");
|
||||
|
||||
|
||||
// var gameSceneConfig = GameSceneHelper.GetSceneConfig(session);
|
||||
//
|
||||
// // 通过chatSceneConfig拿到这个Scene的RouteId
|
||||
@@ -71,6 +69,5 @@ public sealed class C2G_LoginRequestHandler : MessageRPC<C2G_LoginRequest, G2C_L
|
||||
// // 给当前Session添加一个组件,当Session销毁的时候会销毁这个组件。
|
||||
// var accountFlagComponent = session.AddComponent<SessionPlayerComponent>();
|
||||
// accountFlagComponent.AccountID = accountId;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ public static class GateLoginHelper
|
||||
}
|
||||
|
||||
gateUnitSessionComponent.AccountID = gateUnit.AccountID;
|
||||
gateUnitSessionComponent.SessionId = session.RuntimeId;
|
||||
|
||||
|
||||
//安排游戏服务器,并通知进入
|
||||
@@ -56,14 +57,15 @@ public static class GateLoginHelper
|
||||
|
||||
|
||||
//安排进入的聊天服
|
||||
var chatRouteId = await ChatSceneHelper.Online(session.Scene, roleSimpleInfo, session.RuntimeId);
|
||||
var (chatRouteId, sceneRouteId) =
|
||||
await ChatSceneHelper.Online(session.Scene, roleSimpleInfo, session.RuntimeId);
|
||||
if (chatRouteId <= 0)
|
||||
{
|
||||
return ErrorCode.OnlineSceneFailed;
|
||||
}
|
||||
|
||||
routeComponent.AddAddress(RouteType.ChatRoute, chatRouteId);
|
||||
gateUnit.ChatSceneRouteId = chatRouteId;
|
||||
gateUnit.ChatSceneRouteId = sceneRouteId;
|
||||
Log.Info($"连接聊天服成功,gameRouteId:{gameRouteId}");
|
||||
return ErrorCode.Successful;
|
||||
}
|
||||
@@ -75,12 +77,15 @@ public static class GateLoginHelper
|
||||
/// <summary>
|
||||
/// 网关通知其他服务器下线
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="gateUnit"></param>
|
||||
public static async FTask<uint> Offline(GateUnit gateUnit)
|
||||
/// <param name="sessionId"></param>
|
||||
public static async FTask<uint> Offline(GateUnit gateUnit, long sessionId)
|
||||
{
|
||||
await FTask.CompletedTask;
|
||||
//通知服务器下线
|
||||
Log.Info($"断线的session id={sessionId} ChatSceneRouteId={gateUnit.ChatSceneRouteId}");
|
||||
await GameSceneHelper.Offline(gateUnit.Scene, gateUnit.AccountID, sessionId);
|
||||
await ChatSceneHelper.Offline(gateUnit.Scene, gateUnit.AccountID, sessionId,
|
||||
gateUnit.ChatSceneRouteId);
|
||||
return ErrorCode.Successful;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace NB.Gate;
|
||||
|
||||
public static class GateUnitManageComponentSystem
|
||||
{
|
||||
public static GateUnit Add(this GateUnitManageComponent self, Session session, long accountId)
|
||||
public static GateUnit Online(this GateUnitManageComponent self, Session session, long accountId)
|
||||
{
|
||||
if (self.Units.TryGetValue(accountId, out var unit))
|
||||
{
|
||||
@@ -34,11 +34,12 @@ public static class GateUnitManageComponentSystem
|
||||
return self.Units.TryGetValue(accountId, out unit);
|
||||
}
|
||||
|
||||
public static async FTask Remove(this GateUnitManageComponent self, long accountId, bool isDispose = true)
|
||||
public static async FTask Offline(this GateUnitManageComponent self, long accountId, long sessionId,
|
||||
bool isDispose = true)
|
||||
{
|
||||
if (!self.Units.TryGetValue(accountId, out var unit)) return;
|
||||
//通知其他服务器下线
|
||||
var result = await GateLoginHelper.Offline(unit);
|
||||
var result = await GateLoginHelper.Offline(unit, sessionId);
|
||||
if (result != 0)
|
||||
{
|
||||
Log.Error($"通知其他服务器下线失败,错误码:{result}");
|
||||
@@ -52,9 +53,10 @@ public static class GateUnitManageComponentSystem
|
||||
unit.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 回话迭代器
|
||||
/// 会话迭代器
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
@@ -9,7 +9,7 @@ public class GateUnitSessionComponentSystem : DestroySystem<GateUnitSessionCompo
|
||||
var gateUnitManageComponent = self.Scene.GetComponent<GateUnitManageComponent>();
|
||||
if (gateUnitManageComponent != null)
|
||||
{
|
||||
_ = gateUnitManageComponent.Remove(self.AccountID);
|
||||
_ = gateUnitManageComponent.Offline(self.AccountID, self.SessionId);
|
||||
}
|
||||
|
||||
self.AccountID = 0;
|
||||
|
||||
Reference in New Issue
Block a user