fix synapse use mqtt
This commit is contained in:
+58
-64
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RabbitMQ.Client.Events;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Protocol;
|
||||
using SimApi.Communications;
|
||||
using SimApi.Exceptions;
|
||||
using SimApi.Helpers;
|
||||
@@ -16,78 +18,70 @@ 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 rsTopicPrefix = $"{Options.SysName}/{Options.AppName}/rpc/server/";
|
||||
var rsSubOpts = MqttFactory.CreateSubscribeOptionsBuilder()
|
||||
.WithTopicFilter(o =>
|
||||
o.WithTopic($"$queue/{rsTopicPrefix}+").WithRetainHandling(MqttRetainHandling.SendAtSubscribe))
|
||||
.Build();
|
||||
Client.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
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,
|
||||
if (!e.ApplicationMessage.Topic.StartsWith(rsTopicPrefix)) return Task.CompletedTask;
|
||||
var reqBody = e.ApplicationMessage.ConvertPayloadToString();
|
||||
var action = e.ApplicationMessage.Topic.Replace(rsTopicPrefix, string.Empty);
|
||||
var appInfo = e.ApplicationMessage.ResponseTopic.Split(",");
|
||||
logger.LogDebug(
|
||||
"Synapse RPC Server Receive: ({BasicPropertiesMessageId}) {BasicPropertiesReplyTo} -> {BasicPropertiesType}@{OptionsAppName}\n{S}",
|
||||
e.ApplicationMessage.ContentType, appInfo[0], action, 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 method = RpcRegistry.FirstOrDefault(x => x.Key == action);
|
||||
if (method == null) return Task.CompletedTask;
|
||||
var callClass = Sp.CreateScope().ServiceProvider.GetRequiredService(method.Class);
|
||||
var mt = callClass.GetType().GetMethod(method.Method);
|
||||
try
|
||||
{
|
||||
var callClass = Sp.CreateScope().ServiceProvider.GetRequiredService(method.Class);
|
||||
var mt = callClass.GetType().GetMethod(method.Method);
|
||||
var param = Array.Empty<object>();
|
||||
try
|
||||
var pt = mt!.GetParameters()[0].ParameterType;
|
||||
var param = pt == typeof(string)
|
||||
? [reqBody]
|
||||
: new[] { JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption) };
|
||||
var ret = mt.Invoke(callClass, param);
|
||||
res = new SimApiBaseResponse<object>
|
||||
{
|
||||
var pt = mt.GetParameters()[0].ParameterType;
|
||||
if (pt == typeof(string))
|
||||
{
|
||||
param = new[] { reqBody };
|
||||
}
|
||||
else
|
||||
{
|
||||
var paramObj = JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption);
|
||||
param = new[] { paramObj };
|
||||
}
|
||||
|
||||
var ret = mt.Invoke(callClass, param);
|
||||
res = new SimApiBaseResponse<object>
|
||||
{
|
||||
Data = ret
|
||||
};
|
||||
Data = ret
|
||||
};
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
if (ex.InnerException is SimApiException ie)
|
||||
{
|
||||
logger.LogDebug("Synapse RPC调用错误: {Err}", ie.Message);
|
||||
res = new SimApiBaseResponse(ie.Code, ie.Message);
|
||||
}
|
||||
catch (TargetInvocationException e)
|
||||
else
|
||||
{
|
||||
if (e.InnerException is SimApiException ie)
|
||||
{
|
||||
Logger.LogDebug("RPC调用错误: {Err}", ie.Message);
|
||||
res = new SimApiBaseResponse(ie.Code, ie.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = new SimApiBaseResponse(500, e.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogDebug("RPC调用失败: {Err}", e.Message);
|
||||
res = new SimApiBaseResponse(500, e.Message);
|
||||
res = new SimApiBaseResponse(500, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogDebug("Synapse RPC调用失败: {Err}", ex.Message);
|
||||
res = new SimApiBaseResponse(500, ex.Message);
|
||||
}
|
||||
var returnJson = JsonSerializer.Serialize((object)res, SimApiUtil.JsonOption);
|
||||
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);
|
||||
var reply = $"{Options.SysName}/{appInfo[0]}/rpc/client/{appInfo[1]}/{e.ApplicationMessage.ContentType}";
|
||||
var message = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(reply)
|
||||
.WithPayload(returnJson)
|
||||
.WithRetainFlag(false)
|
||||
.Build();
|
||||
if (!Client!.IsConnected) return Task.CompletedTask;
|
||||
Client!.PublishAsync(message, CancellationToken.None).Wait();
|
||||
logger.LogDebug(
|
||||
"Synapse Rpc Server Return: ({BasicPropertiesMessageId}) {BasicPropertiesType}@{OptionsAppName} -> {BasicPropertiesReplyTo}\n{ReturnJson}",
|
||||
e.ApplicationMessage.ContentType, action, Options.AppName, appInfo[0], returnJson);
|
||||
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
RpcServerChannel.BasicConsume(queue, true, "", false, false, null, consumer);
|
||||
Client.SubscribeAsync(rsSubOpts).Wait();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user