초기커밋

This commit is contained in:
2025-05-01 07:20:41 +09:00
commit 98bb2e3c5c
2747 changed files with 646947 additions and 0 deletions

View File

@@ -0,0 +1,336 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using Nettention.Proud;
using RabbitMQ.Client.Events;
using RabbitMQ.Client;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using System.Reflection;
using Newtonsoft.Json;
using NLog;
using MongoDB.Bson.IO;
using ServerCore;
namespace ServerBase;
public abstract partial class RabbitMqConnector : RabbitMQConnectorBase, IRabbitMqSession, IModule, IWithPacketNamespaceVerifier
{
public delegate Task FnServerMessageRecvFromConsumer(BasicDeliverEventArgs ea, IMessage message);
public FnServerMessageRecvFromConsumer? _fnServerMessageRecvFromConsumer;
private readonly PacketReceiver m_packet_receiver;
private ModuleContext m_module_context;
public RabbitMqConnector( ModuleContext moduleContext )
: base( getConfigParamsOrThrow(moduleContext).serviceName
, getConfigParamsOrThrow(moduleContext).address
, getConfigParamsOrThrow(moduleContext).port
, getConfigParamsOrThrow(moduleContext).userName
, getConfigParamsOrThrow(moduleContext).password
, getConfigParamsOrThrow(moduleContext).useSSL )
{
m_module_context = moduleContext;
m_packet_receiver = new PacketReceiver(this);
}
private static (string serviceName, string address, int port, string userName, string password, bool useSSL) getConfigParamsOrThrow(ModuleContext context)
{
if (context.getConfigParam() is not ConfigParam param)
throw new InvalidCastException("IConfigParam must be of type RabbitMqConnector.ConfigParam !!!");
return (
param.ServiceName ?? throw new InvalidOperationException("ServiceName is null !!!"),
param.HostName ?? throw new InvalidOperationException("HostName is null !!!"),
param.Port,
param.UserName ?? throw new InvalidOperationException("Username is null !!!"),
param.Password ?? throw new InvalidOperationException("Password is null !!!"),
param.UseSSL
);
}
public bool isValidPacketNamespace(string toCheckNamespace, IPacketCommand packetCommand)
{
var packet_namespace = ".PacketHandler";
if (null != toCheckNamespace
&& true == toCheckNamespace.Contains(packet_namespace))
{
return true;
}
else
{
ServerCore.Log.getLogger().error($"Invalid PacketNamespace !!!, not included Namespace : {packet_namespace} ⊆ {toCheckNamespace}, packetCommnad:{packetCommand.toBasicString()}");
}
return false;
}
public async Task<Result> startModule()
{
var err_msg = string.Empty;
var result = new Result();
var module_context = getModuleContext();
var config_param = module_context.getConfigParam() as ConfigParam;
NullReferenceCheckHelper.throwIfNull(config_param, () => $"config_param is null !!!");
var fn_receiver = config_param.fnServerMessageRecvFromConsumer;
NullReferenceCheckHelper.throwIfNull(fn_receiver, () => $"fn_receiver is null !!!");
result = onCreateExchangeChannel();
if(result.isFail())
{
err_msg = $"Failed to onCreateExchangeChannel() in startModule() !!! - {config_param.toBasicString()}";
result.setFail(ServerErrorCode.RabbitMqChannelCreateFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
var is_success = await startMessageReceiverByConsumer(fn_receiver);
if(false == is_success)
{
err_msg = $"Failed to startMessageReceiverByConsumer() in startModule() !!! - {config_param.toBasicString()}";
result.setFail(ServerErrorCode.RabbitMqConsumerStartFailed, err_msg);
Log.getLogger().error(result.toBasicString());
return result;
}
return result;
}
public async Task<Result> stopModule()
{
var result = new Result();
return await Task.FromResult(result);
}
public async Task<bool> startMessageReceiverByConsumer(RabbitMqConnector.FnServerMessageRecvFromConsumer fnFromConsumer)
{
if(null == fnFromConsumer)
{
return false;
}
var result = await m_packet_receiver.registerRecvHandlerAll();
if (false == result)
{
Log.getLogger().error("rabbitMq registerRecvHandler error");
return result;
}
_fnServerMessageRecvFromConsumer = fnFromConsumer;
return base.startConsumer();
}
public async Task<bool> onRecvProtocol<T>(BasicDeliverEventArgs ea, T recvProtocol)
where T : Google.Protobuf.IMessage
{
Log.getLogger().info($"receive:{recvProtocol.ToString()} - {toBasicString()}");
Stopwatch? stopwatch = null;
var event_tid = string.Empty;
var server_logic = ServerLogicApp.getServerLogicApp();
var server_config = server_logic.getServerConfig();
if (true == server_config.PerformanceCheckEnable)
{
event_tid = System.Guid.NewGuid().ToString("N");
stopwatch = Stopwatch.StartNew();
}
var receiver = getPacketReceiver();
if (false == receiver.fillupRabbitMqPacketCommand(ea, recvProtocol, out var fillupPacketCommand))
{
Log.getLogger().error($"Invalid received Packet !!! : {recvProtocol.ToString()}");
return false;
}
if (fillupPacketCommand == null)
{
return false;
}
var found_handler = receiver.findRecvHandler(fillupPacketCommand);
if (null == found_handler)
{
Log.getLogger().error($"Unacceptable Packet !!! : {fillupPacketCommand.toBasicString()} - {toBasicString()}");
return false;
}
var check_by_exchange_type = onCheckByExchangeType(ea, recvProtocol);
if (false == check_by_exchange_type) return false;
//var task = Task.Factory.StartNew(async () =>
var task = Task.Run(async () =>
{
var result = await found_handler.onCheckValid(this, recvProtocol);
if (result.isFail())
{
Log.getLogger().error($"Failed to check Valid !!! : {fillupPacketCommand.toBasicString()}");
}
result = await found_handler.onProcessPacket(this, recvProtocol);
if (result.isFail())
{
Log.getLogger().error($"Failed to process Packet !!! : {fillupPacketCommand.toBasicString()}");
}
if (null != stopwatch)
{
var elapsed_msec = stopwatch.ElapsedMilliseconds;
stopwatch.Stop();
Log.getLogger().debug($"{GetType()} MQSSPacket Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{elapsed_msec} - {recvProtocol.toBasicString()}");
}
});
return await Task.FromResult(true);
}
protected override async void onRecvJsonMessageFromConsumer(object? sender, BasicDeliverEventArgs ea)
{
var body = ea.Body.ToArray();
var bodyStr = Encoding.UTF8.GetString(body);
ServerMessage? message = null;
try
{
message = ServerMessage.Parser.ParseJson(bodyStr);
}
catch (Exception e)
{
Log.getLogger().error($"consumer parsing error bodyStr : {bodyStr}, stackTrace : {e.StackTrace}");
return;
}
if(message == null)
{
Log.getLogger().error($"message is null, bodyStr : {bodyStr}");
return;
}
if(_fnServerMessageRecvFromConsumer == null)
{
Log.getLogger().error("_fnServerMessageRecvFromConsumer is null");
return;
}
await _fnServerMessageRecvFromConsumer.Invoke(ea, message);
}
protected override void onRecvProtoMessageFromConsumer(object? sender, BasicDeliverEventArgs ea)
{
}
protected virtual bool onCheckByExchangeType<T>(BasicDeliverEventArgs ea, T recvProtocol)
where T : Google.Protobuf.IMessage
{
return true;
}
public Task<object>? SendKick( string destServer, string name, Int32 delayMS
, Action<Task<object>>? callback )
{
int reqId = nextReqId();
Task<object>? waitTask = null;
if (callback != null)
{
CancellationTokenSource cancelTokenSrc = new CancellationTokenSource(delayMS);
waitTask = registerCompletionSource(reqId, cancelTokenSrc.Token, callback);
if (waitTask == null)
{
return null;
}
}
ServerMessage message = new ServerMessage();
message.KickReq = new ServerMessage.Types.KickReq();
message.KickReq.ReqId = reqId;
message.KickReq.Name = name;
SendMessage(destServer, message);
return waitTask;
}
public void SendMessage(string to, ServerMessage message)
{
IConnection? con = getConnection();
if(con == null)
{
Log.getLogger().error("GetConnection return null");
return;
}
using (var channel = con.CreateModel())
{
Stopwatch? stopwatch = null;
var event_tid = string.Empty;
var server_logic = ServerLogicApp.getServerLogicApp();
var server_config = server_logic.getServerConfig();
if (true == server_config.PerformanceCheckEnable)
{
event_tid = System.Guid.NewGuid().ToString("N");
stopwatch = Stopwatch.StartNew();
}
channel.QueueDeclare( queue: to,
durable: true,
exclusive: false,
autoDelete: true,
arguments: null );
message.MessageTime = Google.Protobuf.WellKnownTypes.Timestamp.FromDateTime(DateTime.UtcNow);
message.MessageSender = getServiceName();
string messageJson = JsonFormatter.Default.Format(message);
var body = Encoding.UTF8.GetBytes(messageJson);
channel.BasicPublish( exchange: "",
routingKey: to,
basicProperties: null,
body: body );
Log.getLogger().info($"send to MQS !!!, msg:{messageJson} - receiver:{to}");
if (null != stopwatch)
{
var elapsed_msec = stopwatch.ElapsedMilliseconds;
stopwatch.Stop();
Log.getLogger().debug($"{GetType()} SMQSPacket Stopwatch Stop : ETID:{event_tid}, ElapsedMSec:{stopwatch.ElapsedMilliseconds} - {message.toBasicString()}");
}
}
}
protected abstract Result onCreateExchangeChannel();
public PacketReceiver getPacketReceiver() => m_packet_receiver;
public ModuleContext getModuleContext() => m_module_context;
public virtual string toBasicString()
{
return $"{this.getTypeName()}";
}
}