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
242 lines
8.4 KiB
C#
242 lines
8.4 KiB
C#
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using NetWorkMessage;
|
||
using Server.Core;
|
||
using MrWu.Debug;
|
||
|
||
namespace ActorCore
|
||
{
|
||
public struct MessageInfo
|
||
{
|
||
/// <summary>
|
||
/// 谁发来的
|
||
/// </summary>
|
||
public ActorId FormActorId;
|
||
|
||
/// <summary>
|
||
/// 包体
|
||
/// </summary>
|
||
public MessageObject MessageObject;
|
||
}
|
||
|
||
public class MailBox : IMailBox
|
||
{
|
||
private readonly Actor actor;
|
||
|
||
private ActorId actorId => actor.ActorId;
|
||
|
||
public MailBoxType MailBoxType => actor.MailBoxType;
|
||
|
||
public int HandleMaxMessageCount => actor.HandleMaxMessageCount;
|
||
|
||
private int actorTypeId => actor.ActorId.ActorTypeId;
|
||
|
||
//这里可以改成普通字典,这里没有线程安全问题
|
||
private readonly ConcurrentDictionary<uint, MessageSenderStruct> requestCallback =
|
||
new ConcurrentDictionary<uint, MessageSenderStruct>();
|
||
|
||
private readonly Dictionary<Type, ActorHandle> actorMessageHandle = new Dictionary<Type, ActorHandle>();
|
||
|
||
private readonly Dictionary<Type, ActorRpcHandle> actorRpcHandles = new Dictionary<Type, ActorRpcHandle>();
|
||
|
||
private readonly List<MessageInfo> list = new List<MessageInfo>();
|
||
|
||
public void RegisterMessageHandle(Type type, ActorHandle handle)
|
||
{
|
||
this.actorMessageHandle[type] = handle;
|
||
}
|
||
|
||
public void RegisterRPCHandle(Type type, ActorRpcHandle rpcHandle)
|
||
{
|
||
this.actorRpcHandles[type] = rpcHandle;
|
||
}
|
||
|
||
public MailBox(Actor actor)
|
||
{
|
||
this.actor = actor;
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
HandleActorMessage();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理Actor消息
|
||
/// </summary>
|
||
private void HandleActorMessage()
|
||
{
|
||
list.Clear();
|
||
ActorMessageQueue.Instance.Fetch(this.actorTypeId, HandleMaxMessageCount, list);
|
||
|
||
// if (this.actorTypeId == ActorTypeId.NetInner)
|
||
// {
|
||
// Debug.Log($"当前数量:{list.Count}");
|
||
// }
|
||
|
||
foreach (MessageInfo messageInfo in list)
|
||
{
|
||
//执行Actor消息
|
||
_ = HandleActorMessage(messageInfo.FormActorId,messageInfo.MessageObject);
|
||
}
|
||
}
|
||
|
||
private async Task HandleActorMessage(ActorId fromActorId, MessageObject messageObject)
|
||
{
|
||
//Debug.Info($"HandleActorMessage {messageObject.GetType()}");
|
||
if (messageObject is IResponse response)
|
||
{
|
||
HandleIActorResponse(response);
|
||
return;
|
||
}
|
||
|
||
if (MailBoxType == MailBoxType.OrderedMessage)
|
||
{
|
||
using (await actor.Wait(CoroutineLockType.MailBox, actorTypeId))
|
||
{
|
||
try
|
||
{
|
||
//Debug.Log($"等待锁! {Thread.CurrentThread.ManagedThreadId}");
|
||
await _HandleActorMessage(fromActorId, messageObject);
|
||
//Debug.Log($"结束锁! {Thread.CurrentThread.ManagedThreadId}");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.Error("MailBox:" + e);
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
await _HandleActorMessage(fromActorId, messageObject);
|
||
}
|
||
}
|
||
|
||
private async Task _HandleActorMessage(ActorId fromActorId,MessageObject messageObject)
|
||
{
|
||
switch (messageObject)
|
||
{
|
||
case IRequest request:
|
||
await HandleIActorRequest(fromActorId,request);
|
||
break;
|
||
default:
|
||
await HandleIActorMessage(fromActorId,messageObject);
|
||
break;
|
||
}
|
||
|
||
//执行完就回收消息 - 如果消息不想被回收 那就不要用池
|
||
ReferencePool.Recycle(messageObject);
|
||
}
|
||
|
||
/// <summary>
|
||
/// RPC 请求消息
|
||
/// </summary>
|
||
/// <param name="fromActorId"></param>>
|
||
/// <param name="request"></param>
|
||
private async Task HandleIActorRequest(ActorId fromActorId,IRequest request)
|
||
{
|
||
//等待处理
|
||
Type type = request.GetType();
|
||
IResponse response = MessageHelper.CreateResponse(type,request.RpcId,0);
|
||
if (!this.actorRpcHandles.TryGetValue(type,out ActorRpcHandle thisHandle))
|
||
{
|
||
Debug.Error($"not found rpc handle:{type} ActorId:{this.actor.ActorId} {this.actorRpcHandles.Count}");
|
||
response.Error = NetErrorCode.ERR_NotFoundHandle;
|
||
}
|
||
|
||
uint rpcId = request.RpcId;
|
||
if (response.Error == 0)
|
||
{
|
||
try
|
||
{
|
||
await thisHandle(fromActorId,request,response);
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
response.Error = NetErrorCode.ERR_RPCFail;
|
||
response.Message = exception.ToString();
|
||
Debug.Log($"exception:{exception}");
|
||
}
|
||
}
|
||
|
||
response.RpcId = rpcId;
|
||
Debug.Log($"Reply:{fromActorId} {response.GetType()}");
|
||
this.actor.Reply(fromActorId,response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// RPC 响应消息
|
||
/// </summary>
|
||
/// <param name="response"></param>
|
||
private void HandleIActorResponse(IResponse response)
|
||
{
|
||
//Debug.Log($"HandleIActorResponse RpcId:{response.RpcId}");
|
||
if (!this.requestCallback.TryRemove(response.RpcId,out MessageSenderStruct actorMessageSender))
|
||
{
|
||
Debug.Warning($"ActorResponse: {response.GetType()}");
|
||
return;
|
||
}
|
||
|
||
Run(actorMessageSender,response);
|
||
}
|
||
|
||
private void Run(MessageSenderStruct self,IResponse response)
|
||
{
|
||
self.SetResult(response);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 普通消息
|
||
/// </summary>
|
||
/// <param name="fromActorId"></param>
|
||
/// <param name="messageObject"></param>
|
||
private async Task HandleIActorMessage(ActorId fromActorId,MessageObject messageObject)
|
||
{
|
||
Type type = messageObject.GetType();
|
||
if (!this.actorMessageHandle.TryGetValue(type, out ActorHandle thisHandle))
|
||
{
|
||
Debug.Error($"not found message handle:{type} ActorId:{this.actor.ActorId}");
|
||
return;
|
||
}
|
||
|
||
//todo 等待处理
|
||
|
||
//此处要加上MailType的判断,是否要等待上一个消息处理完成
|
||
//Debug.Log($"---- id:{this.ActorId.ActorTypeId}");
|
||
await thisHandle(fromActorId,messageObject);
|
||
}
|
||
|
||
|
||
public bool AddActorRpcResponse(uint rpcId, MessageSenderStruct messageSenderStruct)
|
||
{
|
||
return this.requestCallback.TryAdd(rpcId, messageSenderStruct);
|
||
}
|
||
|
||
public bool RemoveActorRpcResponse(uint rpcId,out MessageSenderStruct messageSenderStruct)
|
||
{
|
||
return this.requestCallback.TryRemove(rpcId, out messageSenderStruct);
|
||
}
|
||
|
||
public void Send(ActorId target, MessageObject messageObject)
|
||
{
|
||
if (target.Process == this.actorId.Process)
|
||
{
|
||
//发给内部Actor
|
||
ActorMessageQueue.Instance.Send(this.actorId, target, messageObject);
|
||
return;
|
||
}
|
||
|
||
//发给外部Actor
|
||
NetInnerMessage netInnerMessage = NetInnerMessage.Create();
|
||
netInnerMessage.ActorId = target;
|
||
netInnerMessage.MessageObject = messageObject;
|
||
|
||
ActorMessageQueue.Instance.Send(this.actorId,
|
||
new ActorId(this.actorId.Process, ActorTypeId.NetInner), netInnerMessage);
|
||
}
|
||
}
|
||
} |