完成离线消息发送和上线获取离线消息

This commit is contained in:
2025-08-13 23:44:59 +08:00
parent f8b876ca2f
commit 022cc1ac3e
39 changed files with 499 additions and 85 deletions

View File

@@ -21,6 +21,7 @@ public class
}
var channel = await channelCenter.Create(entity);
response.ChannelId = channel.Id;
}
}

View File

@@ -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;
}
}

View File

@@ -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)
{

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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);
}
}

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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;
}