2023-10-20 12:33:18 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Linq;
|
2023-10-20 15:29:32 +08:00
|
|
|
using System.Reflection;
|
2023-10-20 12:33:18 +08:00
|
|
|
using System.Text;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using RabbitMQ.Client.Events;
|
|
|
|
|
using SimApi.Communications;
|
|
|
|
|
using SimApi.Exceptions;
|
2023-10-20 14:13:53 +08:00
|
|
|
using SimApi.Helpers;
|
2023-10-20 12:33:18 +08:00
|
|
|
using JsonSerializer = System.Text.Json.JsonSerializer;
|
|
|
|
|
|
|
|
|
|
namespace SimApi;
|
|
|
|
|
|
|
|
|
|
public partial class Synapse
|
|
|
|
|
{
|
|
|
|
|
private void RunRpcServer()
|
|
|
|
|
{
|
|
|
|
|
RpcServerChannel = CreateChannel(Options.RpcProcessorNum, "RpcServer");
|
|
|
|
|
var queue = $"{Options.SysName}_{Options.AppName}_server";
|
|
|
|
|
var router = $"server.{Options.AppName}";
|
|
|
|
|
RpcServerChannel.QueueDeclare(queue, true, false, true, null);
|
|
|
|
|
RpcServerChannel.QueueBind(queue, Options.SysName, router, null);
|
|
|
|
|
var consumer = new EventingBasicConsumer(RpcServerChannel);
|
|
|
|
|
consumer.Received += (ch, ea) =>
|
|
|
|
|
{
|
|
|
|
|
var reqBody = Encoding.UTF8.GetString(ea.Body.ToArray());
|
|
|
|
|
Logger.LogDebug(
|
|
|
|
|
"RPC Receive: ({BasicPropertiesMessageId}) {BasicPropertiesReplyTo} -> {BasicPropertiesType}@{OptionsAppName}\n{S}",
|
|
|
|
|
ea.BasicProperties.MessageId, ea.BasicProperties.ReplyTo, ea.BasicProperties.Type, Options.AppName,
|
|
|
|
|
reqBody);
|
|
|
|
|
var res = new SimApiBaseResponse(404, "method not found");
|
|
|
|
|
var method = RpcRegistry.FirstOrDefault(x => x.Key == ea.BasicProperties.Type);
|
|
|
|
|
if (method != null)
|
|
|
|
|
{
|
|
|
|
|
var callClass = Sp.CreateScope().ServiceProvider.GetRequiredService(method.Class);
|
|
|
|
|
var mt = callClass.GetType().GetMethod(method.Method);
|
2023-10-20 15:29:32 +08:00
|
|
|
var param = Array.Empty<object>();
|
2023-10-20 14:13:53 +08:00
|
|
|
try
|
2023-10-20 12:33:18 +08:00
|
|
|
{
|
2023-10-20 14:13:53 +08:00
|
|
|
var pt = mt.GetParameters()[0].ParameterType;
|
|
|
|
|
if (pt == typeof(string))
|
2023-10-20 12:33:18 +08:00
|
|
|
{
|
2023-10-20 15:29:32 +08:00
|
|
|
param = new[] { reqBody };
|
2023-10-20 12:33:18 +08:00
|
|
|
}
|
2023-10-20 14:13:53 +08:00
|
|
|
else
|
2023-10-20 12:33:18 +08:00
|
|
|
{
|
2023-10-23 17:39:27 +08:00
|
|
|
var paramObj = JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption);
|
2023-10-20 15:29:32 +08:00
|
|
|
param = new[] { paramObj };
|
2023-10-20 12:33:18 +08:00
|
|
|
}
|
2024-04-16 06:29:21 +08:00
|
|
|
|
2023-10-20 15:29:32 +08:00
|
|
|
var ret = mt.Invoke(callClass, param);
|
2024-04-16 06:29:21 +08:00
|
|
|
res = new SimApiBaseResponse<object>
|
|
|
|
|
{
|
|
|
|
|
Data = ret
|
|
|
|
|
};
|
2023-10-20 12:33:18 +08:00
|
|
|
}
|
2023-10-20 15:29:32 +08:00
|
|
|
catch (TargetInvocationException e)
|
2023-10-20 14:13:53 +08:00
|
|
|
{
|
2023-10-23 17:39:27 +08:00
|
|
|
if (e.InnerException is SimApiException ie)
|
2023-10-20 15:29:32 +08:00
|
|
|
{
|
|
|
|
|
Logger.LogDebug("RPC调用错误: {Err}", ie.Message);
|
|
|
|
|
res = new SimApiBaseResponse(ie.Code, ie.Message);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
res = new SimApiBaseResponse(500, e.Message);
|
|
|
|
|
}
|
2023-10-20 14:13:53 +08:00
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogDebug("RPC调用失败: {Err}", e.Message);
|
|
|
|
|
res = new SimApiBaseResponse(500, e.Message);
|
|
|
|
|
}
|
2023-10-20 12:33:18 +08:00
|
|
|
}
|
2023-10-20 14:13:53 +08:00
|
|
|
|
2023-10-23 17:39:27 +08:00
|
|
|
var returnJson = JsonSerializer.Serialize((object)res, SimApiUtil.JsonOption);
|
2023-10-20 12:33:18 +08:00
|
|
|
var reply = $"client.{ea.BasicProperties.ReplyTo}.{ea.BasicProperties.AppId}";
|
|
|
|
|
var props = RpcServerChannel.CreateBasicProperties();
|
|
|
|
|
props.AppId = Options.AppId;
|
|
|
|
|
props.CorrelationId = ea.BasicProperties.MessageId;
|
|
|
|
|
props.MessageId = Guid.NewGuid().ToString();
|
|
|
|
|
props.ReplyTo = Options.AppName;
|
|
|
|
|
props.Type = ea.BasicProperties.Type;
|
|
|
|
|
RpcServerChannel.BasicPublish(Options.SysName, reply, false, props, Encoding.UTF8.GetBytes(returnJson));
|
|
|
|
|
Logger.LogDebug(
|
|
|
|
|
"Rpc Return: ({BasicPropertiesMessageId}) {BasicPropertiesType}@{OptionsAppName} -> {BasicPropertiesReplyTo}\n{ReturnJson}",
|
|
|
|
|
ea.BasicProperties.MessageId, ea.BasicProperties.Type, Options.AppName, ea.BasicProperties.ReplyTo,
|
|
|
|
|
returnJson);
|
|
|
|
|
};
|
|
|
|
|
RpcServerChannel.BasicConsume(queue, true, "", false, false, null, consumer);
|
|
|
|
|
}
|
|
|
|
|
}
|