add headers

This commit is contained in:
2024-09-05 12:59:57 +08:00
parent 8f6b853b6c
commit 7dc2ac6a86
3 changed files with 59 additions and 30 deletions
+15 -8
View File
@@ -1,10 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MQTTnet; using MQTTnet;
using MQTTnet.Packets;
using SimApi.Communications; using SimApi.Communications;
using SimApi.Helpers; using SimApi.Helpers;
@@ -38,7 +40,7 @@ public partial class Synapse
Client!.SubscribeAsync(rcSubOpts).Wait(); Client!.SubscribeAsync(rcSubOpts).Wait();
} }
private string? FireRpc(string app, string action, object? param) private string? FireRpc(string app, string action, object? param, Dictionary<string, string>? headers = null)
{ {
string paramJson; string paramJson;
if (param is string strParam) if (param is string strParam)
@@ -54,18 +56,23 @@ public partial class Synapse
var messageId = Guid.NewGuid().ToString(); var messageId = Guid.NewGuid().ToString();
var tcs = new TaskCompletionSource<string>(); var tcs = new TaskCompletionSource<string>();
ResponseCompletionSources.Add(messageId, tcs); ResponseCompletionSources.Add(messageId, tcs);
var message = new MqttApplicationMessageBuilder() var messageBuilder = new MqttApplicationMessageBuilder()
.WithTopic(topic) .WithTopic(topic)
.WithPayload(paramJson) .WithPayload(paramJson)
.WithResponseTopic($"{Options.AppName},{Options.AppId}") .WithResponseTopic($"{Options.AppName},{Options.AppId},{messageId}")
.WithContentType(messageId) .WithContentType("application/json")
.WithRetainFlag(false) .WithRetainFlag(false);
.Build(); foreach (var h in headers ?? new Dictionary<string, string>())
{
messageBuilder.WithUserProperty(h.Key, h.Value);
}
var message = messageBuilder.Build();
if (!Client!.IsConnected) return null; if (!Client!.IsConnected) return null;
Client.PublishAsync(message, CancellationToken.None).Wait(); Client.PublishAsync(message, CancellationToken.None).Wait();
logger.LogDebug( logger.LogDebug(
"Synapse RPC Client Request: ({PropsMessageId}) {OptionsAppName} -> {Action}@{App}\n{ParamJson}", messageId, "Synapse RPC Client Request: ({PropsMessageId}) {OptionsAppName} -> {Action}@{App}\n{ParamJson}\nHeaders: {Headers}",
Options.AppName, action, app, paramJson); messageId, Options.AppName, action, app, paramJson, JsonSerializer.Serialize(headers));
string response; string response;
try try
+19 -10
View File
@@ -28,8 +28,7 @@ public partial class Synapse
var appInfo = e.ApplicationMessage.ResponseTopic.Split(","); var appInfo = e.ApplicationMessage.ResponseTopic.Split(",");
logger.LogDebug( logger.LogDebug(
"Synapse RPC Server Receive: ({BasicPropertiesMessageId}) {BasicPropertiesReplyTo} -> {BasicPropertiesType}@{OptionsAppName}\n{S}", "Synapse RPC Server Receive: ({BasicPropertiesMessageId}) {BasicPropertiesReplyTo} -> {BasicPropertiesType}@{OptionsAppName}\n{S}",
e.ApplicationMessage.ContentType, appInfo[0], action, Options.AppName, appInfo[2], appInfo[0], action, Options.AppName, reqBody);
reqBody);
SimApiBaseResponse res; SimApiBaseResponse res;
var method = RpcRegistry.FirstOrDefault(x => x.Key == action); var method = RpcRegistry.FirstOrDefault(x => x.Key == action);
if (method == null) if (method == null)
@@ -44,17 +43,27 @@ public partial class Synapse
{ {
var methodParams = mt!.GetParameters(); var methodParams = mt!.GetParameters();
object? ret; object? ret;
if (methodParams.Length == 0) switch (methodParams.Length)
{
ret = mt.Invoke(callClass, []);
}
else
{ {
case 1:
var pt = mt.GetParameters()[0].ParameterType; var pt = mt.GetParameters()[0].ParameterType;
var param = pt == typeof(string) var param = pt == typeof(string)
? [reqBody] ? [reqBody]
: new[] { JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption) }; : new[] { JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption) };
ret = mt.Invoke(callClass, param); ret = mt.Invoke(callClass, param);
break;
case 2:
var headerData =
e.ApplicationMessage.UserProperties.ToDictionary(x => x.Name, x => x.Value);
var pt2 = mt.GetParameters()[0].ParameterType;
var param2 = pt2 == typeof(string)
? [reqBody]
: new[] { JsonSerializer.Deserialize(reqBody, pt2, SimApiUtil.JsonOption), headerData };
ret = mt.Invoke(callClass, param2);
break;
default:
ret = mt.Invoke(callClass, []);
break;
} }
res = new SimApiBaseResponse<object?> res = new SimApiBaseResponse<object?>
@@ -71,7 +80,7 @@ public partial class Synapse
} }
else else
{ {
logger.LogError("Synapse RPC 方法异常: {Err}\n{Stack}", ex.Message,ex.StackTrace); logger.LogError("Synapse RPC 方法异常: {Err}\n{Stack}", ex.Message, ex.StackTrace);
res = new SimApiBaseResponse(500, ex.Message); res = new SimApiBaseResponse(500, ex.Message);
} }
} }
@@ -83,7 +92,7 @@ public partial class Synapse
} }
var returnJson = JsonSerializer.Serialize((object)res, SimApiUtil.JsonOption); var returnJson = JsonSerializer.Serialize((object)res, SimApiUtil.JsonOption);
var reply = $"{Options.SysName}/{appInfo[0]}/rpc/client/{appInfo[1]}/{e.ApplicationMessage.ContentType}"; var reply = $"{Options.SysName}/{appInfo[0]}/rpc/client/{appInfo[1]}/{appInfo[2]}";
var message = new MqttApplicationMessageBuilder() var message = new MqttApplicationMessageBuilder()
.WithTopic(reply) .WithTopic(reply)
.WithPayload(returnJson) .WithPayload(returnJson)
@@ -93,7 +102,7 @@ public partial class Synapse
Client.PublishAsync(message, CancellationToken.None).Wait(); Client.PublishAsync(message, CancellationToken.None).Wait();
logger.LogDebug( logger.LogDebug(
"Synapse Rpc Server Return: ({BasicPropertiesMessageId}) {BasicPropertiesType}@{OptionsAppName} -> {BasicPropertiesReplyTo}\n{ReturnJson}", "Synapse Rpc Server Return: ({BasicPropertiesMessageId}) {BasicPropertiesType}@{OptionsAppName} -> {BasicPropertiesReplyTo}\n{ReturnJson}",
e.ApplicationMessage.ContentType, action, Options.AppName, appInfo[0], returnJson); appInfo[2], action, Options.AppName, appInfo[0], returnJson);
return Task.CompletedTask; return Task.CompletedTask;
}; };
+20 -7
View File
@@ -87,9 +87,11 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
/// <param name="appName"></param> /// <param name="appName"></param>
/// <param name="method"></param> /// <param name="method"></param>
/// <param name="param"></param> /// <param name="param"></param>
/// <param name="headers"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public SimApiBaseResponse<T> Rpc<T>(string appName, string method, dynamic? param = null) public SimApiBaseResponse<T> Rpc<T>(string appName, string method, dynamic? param = null,
Dictionary<string, string>? headers = null)
{ {
var res = new SimApiBaseResponse(500, "Synapse Rpc Client Disabled!"); var res = new SimApiBaseResponse(500, "Synapse Rpc Client Disabled!");
if (Options.DisableRpcClient) if (Options.DisableRpcClient)
@@ -98,7 +100,7 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
} }
else else
{ {
var data = FireRpc(appName, method, param); var data = FireRpc(appName, method, param, headers);
res = JsonSerializer.Deserialize<SimApiBaseResponse<T>>(data, SimApiUtil.JsonOption); res = JsonSerializer.Deserialize<SimApiBaseResponse<T>>(data, SimApiUtil.JsonOption);
} }
@@ -111,10 +113,12 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
/// <param name="appName"></param> /// <param name="appName"></param>
/// <param name="method"></param> /// <param name="method"></param>
/// <param name="param"></param> /// <param name="param"></param>
/// <param name="headers"></param>
/// <returns></returns> /// <returns></returns>
public SimApiBaseResponse<object> Rpc(string appName, string method, dynamic? param = null) public SimApiBaseResponse<object> Rpc(string appName, string method, dynamic? param = null,
Dictionary<string, string>? headers = null)
{ {
return Rpc<object>(appName, method, param); return Rpc<object>(appName, method, param, headers);
} }
@@ -141,7 +145,7 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
} }
/// <summary> /// <summary>
/// 发送一个事件 /// 发送一个事件x
/// </summary> /// </summary>
/// <param name="eventName"></param> /// <param name="eventName"></param>
/// <param name="param"></param> /// <param name="param"></param>
@@ -271,10 +275,19 @@ public partial class Synapse(SimApiOptions simApiOptions, ILogger<Synapse> logge
var callClass = sp.CreateScope().ServiceProvider.GetRequiredService(tmp.Class!); var callClass = sp.CreateScope().ServiceProvider.GetRequiredService(tmp.Class!);
var mt = callClass.GetType().GetMethod(tmp.Method); var mt = callClass.GetType().GetMethod(tmp.Method);
if (mt!.GetParameters().Length > 1) if (mt!.GetParameters().Length > 2)
{ {
logger.LogError( logger.LogError(
"Synapse Rpc Register Error: Only one or none parameter supported. {Key} -> {Method}@{Class}", "Synapse Rpc Register Error: Only 1,2 or none parameter supported. {Key} -> {Method}@{Class}",
tmp.Key, tmp.Method, tmp.Class.Name);
continue;
}
if (mt.GetParameters().Length == 2 &&
mt.GetParameters()[1].ParameterType != typeof(Dictionary<string, string>))
{
logger.LogError(
"Synapse Rpc Register Error: RpcMethod Parameter 2 must be Dictionary<string, string>. {Key} -> {Method}@{Class}",
tmp.Key, tmp.Method, tmp.Class.Name); tmp.Key, tmp.Method, tmp.Class.Name);
continue; continue;
} }