feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
8
GameNetModule/EventDispatcher/GameNetDispatcher.cs
Normal file
8
GameNetModule/EventDispatcher/GameNetDispatcher.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using Server.Core;
|
||||
|
||||
namespace Server.Net
|
||||
{
|
||||
public class GameNetDispatcher : MultiHandleBaseDispatcher<GameNetDispatcher,int,object>
|
||||
{
|
||||
}
|
||||
}
|
||||
29
GameNetModule/EventDispatcher/GameNetMsgId.cs
Normal file
29
GameNetModule/EventDispatcher/GameNetMsgId.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Server.Core;
|
||||
|
||||
namespace Server.Net
|
||||
{
|
||||
public class GameNetMsgId
|
||||
{
|
||||
public static int curSor = 0;
|
||||
|
||||
// /// <summary>
|
||||
// /// 会话已连接
|
||||
// /// </summary>
|
||||
// public static readonly uint SessionConnected = ++curSor;
|
||||
|
||||
/// <summary>
|
||||
/// 会话断开
|
||||
/// </summary>
|
||||
public static readonly int SessionDisConnected = ++curSor;
|
||||
|
||||
/// <summary>
|
||||
/// 会话绑定用户事件
|
||||
/// </summary>
|
||||
public static readonly int SessionBindUser = ++curSor;
|
||||
|
||||
/// <summary>
|
||||
/// 会话解除用户绑定
|
||||
/// </summary>
|
||||
public static readonly int SessionUnBindUser = ++curSor;
|
||||
}
|
||||
}
|
||||
150
GameNetModule/EventDispatcher/MessageDispatcher.cs
Normal file
150
GameNetModule/EventDispatcher/MessageDispatcher.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using MrWu.Debug;
|
||||
using Server.Core;
|
||||
|
||||
namespace Server.Net
|
||||
{
|
||||
public delegate Task MessageDispatcherDelegate(GamePacket gamePacket);
|
||||
|
||||
/// <summary>
|
||||
/// 网络消息 分发器
|
||||
/// </summary>
|
||||
public sealed class MessageDispatcher : SingleInstance<MessageDispatcher>
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否需要按顺序执行 一般来说子游戏需要按顺序执行,中心服务器不需要按顺序等待
|
||||
/// </summary>
|
||||
public bool IsOrderMessage { get; private set; }
|
||||
|
||||
private ConcurrentQueue<GamePacket> packes = new ConcurrentQueue<GamePacket>();
|
||||
|
||||
public void AddPack(GamePacket gamePacket)
|
||||
{
|
||||
//Debug.Info($"添加一个待处理包裹:{gamePacket.OpCode}");
|
||||
packes.Enqueue(gamePacket);
|
||||
}
|
||||
|
||||
private CoroutineLockManager coroutineLockManager;
|
||||
|
||||
private Dictionary<int, MessageDispatcherDelegate> listeners =
|
||||
new Dictionary<int, MessageDispatcherDelegate>();
|
||||
|
||||
public void Start(bool isOrderMessage, CoroutineLockManager coroutineLockManager)
|
||||
{
|
||||
this.IsOrderMessage = isOrderMessage;
|
||||
this.coroutineLockManager = coroutineLockManager;
|
||||
}
|
||||
|
||||
public void AddListener(int msgId, MessageDispatcherDelegate messageDispatcherDelegate)
|
||||
{
|
||||
listeners[msgId] = messageDispatcherDelegate;
|
||||
}
|
||||
|
||||
public void RemoveListener(int msgId, MessageDispatcherDelegate messageDispatcherDelegate)
|
||||
{
|
||||
if (listeners.ContainsKey(msgId) && listeners[msgId] == messageDispatcherDelegate)
|
||||
{
|
||||
listeners.Remove(msgId);
|
||||
}
|
||||
}
|
||||
|
||||
private const int MaxCnt = 200;
|
||||
|
||||
private int PackCnt;
|
||||
|
||||
//此处可以优化
|
||||
public void Handle()
|
||||
{
|
||||
PackCnt = packes.Count;
|
||||
if (PackCnt > MaxCnt)
|
||||
{
|
||||
Debug.ImportantLog($"单帧处理消息过多! {packes.Count}");
|
||||
PackCnt = MaxCnt;
|
||||
//进行统计
|
||||
}
|
||||
|
||||
while (PackCnt -- > 0)
|
||||
{
|
||||
if (!packes.TryDequeue(out GamePacket pack))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!listeners.TryGetValue(pack.OpCode, out var handle))
|
||||
{
|
||||
Debug.Error($"这个客户端消息没有处理器! {pack.OpCode}");
|
||||
pack.Dispose();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsOrderMessage)
|
||||
{
|
||||
_ = SafeInvokeOrderMessage(pack, handle);
|
||||
// //同用户的消息顺序才需要等待上一个包的完成
|
||||
// using (await coroutineLockManager.Wait(CoroutineLockType.ClientMessage, pack.Session.Id))
|
||||
// {
|
||||
// await SafeInvoke(pack, handle);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = SafeInvoke(pack, handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按玩家的顺序来处理
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task SafeInvokeOrderMessage(GamePacket packet, MessageDispatcherDelegate handler)
|
||||
{
|
||||
using (await coroutineLockManager.Wait(CoroutineLockType.ClientMessage, packet.Session.InstanceId))
|
||||
{
|
||||
await SafeInvoke(packet, handler);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SafeInvoke(GamePacket packet, MessageDispatcherDelegate handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (packet.Session.IsDisConnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long key = Debug.StartTiming();
|
||||
await handler(packet);
|
||||
double _runtime = Debug.GetRunTime(key);
|
||||
if (_runtime > 1000f)
|
||||
{
|
||||
Debug.Warning($"消息执行处理慢:{packet.OpCode} {_runtime}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Error($"消息处理异常:{packet.OpCode} {e.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await PacketDispose(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PacketDispose(GamePacket packet)
|
||||
{
|
||||
try
|
||||
{
|
||||
await packet.Wait();
|
||||
}
|
||||
finally
|
||||
{
|
||||
packet.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user