Compare commits

...
11 Commits
Author SHA1 Message Date
xrain af6bc86a0c ErrorWhen Code Antis 2025-10-26 01:08:07 +08:00
xrain fc7714198f add loginitem update 2025-10-25 17:12:39 +08:00
xrain d2b5f14e78 fix some 2025-10-25 17:03:43 +08:00
xrain 116cbcdc7f update to 9 2025-10-14 02:55:29 +08:00
xrain 4e1b7d4845 update to 9 2025-10-14 02:20:37 +08:00
xrain 71acb35df9 cancle json refrence 2025-08-13 17:28:24 +08:00
xrain 67cc7346dc use concurrentDic 2025-05-17 21:17:43 +08:00
xrain 8627ae61fa use lock 2025-05-17 21:11:27 +08:00
xrain 02523028db add task.run 2025-05-17 20:40:48 +08:00
xrain 7d39ab5e0b add task.run 2025-05-17 20:38:39 +08:00
xrain 87fda473d3 udpate 2025-05-14 06:26:10 +08:00
13 changed files with 222 additions and 144 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
- name: Setup .NET Core - name: Setup .NET Core
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: "8.0.200" dotnet-version: "9.0.305"
- name: Publish - name: Publish
run: | run: |
version=`git describe --tags` version=`git describe --tags`
+6 -8
View File
@@ -1,13 +1,11 @@
using System.ComponentModel.DataAnnotations; namespace SimApi.Communications;
namespace SimApi.Communications;
/// <summary> /// <summary>
/// 只有ID的请求 /// 只有ID的请求
/// </summary> /// </summary>
public class SimApiIdOnlyRequest public class SimApiIdOnlyRequest
{ {
[Required] public int Id { get; set; } public required int Id { get; set; }
} }
/// <summary> /// <summary>
@@ -15,7 +13,7 @@ public class SimApiIdOnlyRequest
/// </summary> /// </summary>
public class SimApiStringIdOnlyRequest public class SimApiStringIdOnlyRequest
{ {
[Required] public string? Id { get; set; } public required string Id { get; set; }
} }
/// <summary> /// <summary>
@@ -24,7 +22,7 @@ public class SimApiStringIdOnlyRequest
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public class SimApiOneFieldRequest<T> public class SimApiOneFieldRequest<T>
{ {
[Required] public T? Data { get; set; } public required T Data { get; set; }
} }
/// <summary> /// <summary>
@@ -32,6 +30,6 @@ public class SimApiOneFieldRequest<T>
/// </summary> /// </summary>
public class SimApiBasePageRequest public class SimApiBasePageRequest
{ {
[Required] public int Page { get; set; } public required int Page { get; set; }
[Required] public int Count { get; set; } public required int Count { get; set; }
} }
+4 -4
View File
@@ -7,8 +7,8 @@ namespace SimApi.Communications;
/// </summary> /// </summary>
public class SimApiLoginItem public class SimApiLoginItem
{ {
public string? Id { get; set; } public string Id { get; set; } = null!;
public string[] Type { get; set; } = new[] { "user" }; public string[] Type { get; set; } = ["user"];
public Dictionary<string, string>? Meta { get; set; } = null; public Dictionary<string, string> Meta { get; set; } = [];
public object? Extra { get; set; } = null; public object? Extra { get; set; }
}; };
+6 -5
View File
@@ -1,4 +1,5 @@
using SimApi.Communications; using System.Diagnostics.CodeAnalysis;
using SimApi.Communications;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
@@ -53,7 +54,7 @@ public class SimApiBaseController : Controller
/// <param name="condition">检测条件</param> /// <param name="condition">检测条件</param>
/// <param name="code">错误代码</param> /// <param name="code">错误代码</param>
/// <param name="message">错误描述</param> /// <param name="message">错误描述</param>
protected static void ErrorWhen(bool condition, int code = 400, string message = "") protected static void ErrorWhen([DoesNotReturnIf(true)] bool condition, int code = 400, string message = "")
{ {
if (condition) if (condition)
{ {
@@ -68,7 +69,7 @@ public class SimApiBaseController : Controller
/// <param name="condition">检测条件</param> /// <param name="condition">检测条件</param>
/// <param name="code">错误代码</param> /// <param name="code">错误代码</param>
/// <param name="message">错误描述</param> /// <param name="message">错误描述</param>
protected static void ErrorWhenTrue(bool condition, int code = 400, string message = "") protected static void ErrorWhenTrue([DoesNotReturnIf(true)] bool condition, int code = 400, string message = "")
{ {
ErrorWhen(condition, code, message); ErrorWhen(condition, code, message);
} }
@@ -80,7 +81,7 @@ public class SimApiBaseController : Controller
/// <param name="condition"></param> /// <param name="condition"></param>
/// <param name="code"></param> /// <param name="code"></param>
/// <param name="message"></param> /// <param name="message"></param>
protected static void ErrorWhenFalse(bool condition, int code = 400, string message = "") protected static void ErrorWhenFalse([DoesNotReturnIf(false)] bool condition, int code = 400, string message = "")
{ {
ErrorWhen(!condition, code, message); ErrorWhen(!condition, code, message);
} }
@@ -91,7 +92,7 @@ public class SimApiBaseController : Controller
/// <param name="condition">检测条件</param> /// <param name="condition">检测条件</param>
/// <param name="code">错误代码</param> /// <param name="code">错误代码</param>
/// <param name="message">错误描述</param> /// <param name="message">错误描述</param>
protected static void ErrorWhenNull(object? condition, int code = 404, string message = "请求的资源不存在") protected static void ErrorWhenNull([NotNull] object? condition, int code = 404, string message = "请求的资源不存在")
{ {
ErrorWhen(condition == null, code, message); ErrorWhen(condition == null, code, message);
} }
+13 -3
View File
@@ -1,6 +1,4 @@
#nullable enable
using System; using System;
using System.Collections.Generic;
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Distributed;
using SimApi.Communications; using SimApi.Communications;
@@ -25,6 +23,18 @@ public class SimApiAuth(IDistributedCache cache)
return token; return token;
} }
/// <summary>
/// 更新登陆信息
/// </summary>
/// <param name="loginItem"></param>
/// <param name="token"></param>
/// <returns></returns>
public string Update(SimApiLoginItem loginItem, string token)
{
cache.SetString(token, JsonSerializer.Serialize(loginItem));
return token;
}
/// <summary> /// <summary>
/// 获取登陆信息 /// 获取登陆信息
/// </summary> /// </summary>
@@ -33,7 +43,7 @@ public class SimApiAuth(IDistributedCache cache)
public SimApiLoginItem? GetLogin(string token) public SimApiLoginItem? GetLogin(string token)
{ {
var login = cache.GetString(token); var login = cache.GetString(token);
return login != null ? JsonSerializer.Deserialize<SimApiLoginItem>(login) : default; return login != null ? JsonSerializer.Deserialize<SimApiLoginItem>(login) : null;
} }
/// <summary> /// <summary>
+1 -1
View File
@@ -5,7 +5,7 @@ namespace SimApi.Helpers;
public class SimApiCache(IDistributedCache cache) public class SimApiCache(IDistributedCache cache)
{ {
private const string Prefix = "SimApi:Cache"; private const string Prefix = "SimApi:Cache:";
public void Set(string key, object value, DistributedCacheEntryOptions? options = null) public void Set(string key, object value, DistributedCacheEntryOptions? options = null)
{ {
+1 -1
View File
@@ -14,7 +14,7 @@ public class SimApiJobWebAuth(string user, string pass) : IDashboardAuthorizatio
var authHeader = httpContext.Request.Headers["Authorization"].FirstOrDefault(); var authHeader = httpContext.Request.Headers["Authorization"].FirstOrDefault();
if (authHeader != null && authHeader.StartsWith("Basic ")) if (authHeader != null && authHeader.StartsWith("Basic "))
{ {
var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim(); var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1].Trim();
var decodedUsernamePassword = Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword)); var decodedUsernamePassword = Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));
var username = decodedUsernamePassword.Split(':', 2)[0]; var username = decodedUsernamePassword.Split(':', 2)[0];
var password = decodedUsernamePassword.Split(':', 2)[1]; var password = decodedUsernamePassword.Split(':', 2)[1];
+36 -2
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
@@ -7,6 +8,7 @@ using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Text.Unicode; using System.Text.Unicode;
using System.Xml.Serialization;
namespace SimApi.Helpers; namespace SimApi.Helpers;
@@ -22,9 +24,10 @@ public static class SimApiUtil
/// </summary> /// </summary>
public static JsonSerializerOptions JsonOption => new() public static JsonSerializerOptions JsonOption => new()
{ {
// ReferenceHandler = ReferenceHandler.Preserve,
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
}; };
/// <summary> /// <summary>
@@ -62,12 +65,43 @@ public static class SimApiUtil
return stringBuilder.ToString(); return stringBuilder.ToString();
} }
/// <summary>
/// sha1加密字符串
/// </summary>
/// <param name="source">源字符串</param>
/// <param name="mode">加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位</param>
/// <returns></returns>
public static string Sha1(string source, string mode = "x2")
{
var hash = SHA1.HashData(Encoding.UTF8.GetBytes(source));
var sb = new StringBuilder(hash.Length * 2);
foreach (var b in hash)
{
sb.Append(b.ToString(mode));
}
return sb.ToString();
}
/// <summary>
/// 将XML字符串序列化为对象
/// </summary>
/// <param name="source"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T XmlDeserialize<T>(string source)
{
var xmlConvertor = new XmlSerializer(typeof(T));
using var reader = new StringReader(source);
return (T)xmlConvertor.Deserialize(reader)!;
}
/// <summary> /// <summary>
/// 将对象序列化成JSON (控制台输出中文不会被编码) /// 将对象序列化成JSON (控制台输出中文不会被编码)
/// </summary> /// </summary>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <returns></returns> /// <returns></returns>
public static string Json(object obj) public static string Json(object? obj)
{ {
return JsonSerializer.Serialize(obj, JsonOption); return JsonSerializer.Serialize(obj, JsonOption);
} }
+7 -6
View File
@@ -14,8 +14,8 @@
<SynchReleaseVersion>false</SynchReleaseVersion> <SynchReleaseVersion>false</SynchReleaseVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageVersion>5.0.2</PackageVersion> <PackageVersion>5.0.2</PackageVersion>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -23,14 +23,15 @@
<Folder Include="Exceptions\"/> <Folder Include="Exceptions\"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.17" /> <PackageReference Include="Hangfire.AspNetCore" Version="1.8.18" />
<PackageReference Include="Hangfire.Console" Version="1.4.3" /> <PackageReference Include="Hangfire.Console" Version="1.4.3" />
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.9.4" /> <PackageReference Include="Hangfire.Redis.StackExchange" Version="1.12.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.1" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.5" />
<PackageReference Include="Minio" Version="6.0.4" /> <PackageReference Include="Minio" Version="6.0.4" />
<PackageReference Include="MQTTnet" Version="5.0.1.1416" /> <PackageReference Include="MQTTnet" Version="5.0.1.1416" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="7.2.0" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="8.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.2.0" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="8.1.1" />
<PackageReference Include="System.Text.Json" Version="9.0.10" />
</ItemGroup> </ItemGroup>
<ProjectExtensions> <ProjectExtensions>
<MonoDevelop> <MonoDevelop>
+34 -7
View File
@@ -247,7 +247,10 @@ public static class SimApiExtensions
{ {
builder.AddControllers(opt => opt.Filters.Add<SimApiResponseFilter>()) builder.AddControllers(opt => opt.Filters.Add<SimApiResponseFilter>())
.AddXmlSerializerFormatters() .AddXmlSerializerFormatters()
.AddJsonOptions(opt => opt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase); .AddJsonOptions(opt =>
{
opt.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
} }
builder.AddSingleton(simApiOptions); builder.AddSingleton(simApiOptions);
@@ -328,22 +331,46 @@ public static class SimApiExtensions
logger.LogInformation("开始配置SimApiAuth..."); logger.LogInformation("开始配置SimApiAuth...");
builder.UseMiddleware<SimApiAuthMiddleware>(); builder.UseMiddleware<SimApiAuthMiddleware>();
builder.MapControllerRoute(name: "GetUserInfo", pattern: "/user/info", builder.MapControllerRoute(name: "GetUserInfo", pattern: "/user/info",
defaults: new { controller = "SimApiCommon", action = "UserInfo" }); defaults: new
{
controller = "SimApiCommon",
action = "UserInfo"
});
builder.MapControllerRoute(name: "CheckLogin", pattern: "/auth/check", builder.MapControllerRoute(name: "CheckLogin", pattern: "/auth/check",
defaults: new { controller = "SimApiCommon", action = "CheckLogin" }); defaults: new
{
controller = "SimApiCommon",
action = "CheckLogin"
});
builder.MapControllerRoute(name: "Logout", pattern: "/auth/logout", builder.MapControllerRoute(name: "Logout", pattern: "/auth/logout",
defaults: new { controller = "SimApiCommon", action = "Logout" }); defaults: new
{
controller = "SimApiCommon",
action = "Logout"
});
if (options.EnableCoceSdk) if (options.EnableCoceSdk)
{ {
logger.LogInformation("开始配置CoceAppSdk...\nApi入口: {ApiUrl}\nAuth入口:{AuthUrl}n\nAppId: {AppId}", logger.LogInformation("开始配置CoceAppSdk...\nApi入口: {ApiUrl}\nAuth入口:{AuthUrl}n\nAppId: {AppId}",
options.CoceSdkOptions.ApiEndpoint, options.CoceSdkOptions.AuthEndpoint, options.CoceSdkOptions.ApiEndpoint, options.CoceSdkOptions.AuthEndpoint,
options.CoceSdkOptions.AppId); options.CoceSdkOptions.AppId);
builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/auth/login", builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/auth/login",
defaults: new { controller = "Coce", action = "Login" }); defaults: new
{
controller = "Coce",
action = "Login"
});
builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/user/groups", builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/user/groups",
defaults: new { controller = "Coce", action = "ListGroups" }); defaults: new
{
controller = "Coce",
action = "ListGroups"
});
builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/auth/config", builder.MapControllerRoute(name: "LoginUseCoce", pattern: "/auth/config",
defaults: new { controller = "Coce", action = "GetConfig" }); defaults: new
{
controller = "Coce",
action = "GetConfig"
});
} }
} }
+5 -2
View File
@@ -18,6 +18,8 @@ public partial class Synapse
private void RunEventServer() private void RunEventServer()
{ {
Client!.ApplicationMessageReceivedAsync += async e => Client!.ApplicationMessageReceivedAsync += async e =>
{
await Task.Run(async () =>
{ {
if (!e.ApplicationMessage.Topic.StartsWith(EventServerTopicPrefix)) return; if (!e.ApplicationMessage.Topic.StartsWith(EventServerTopicPrefix)) return;
var reqBody = e.ApplicationMessage.ConvertPayloadToString(); var reqBody = e.ApplicationMessage.ConvertPayloadToString();
@@ -37,8 +39,8 @@ public partial class Synapse
{ {
var pt = mt.GetParameters()[1].ParameterType; var pt = mt.GetParameters()[1].ParameterType;
mt.Invoke(callClass, pt == typeof(string) mt.Invoke(callClass, pt == typeof(string)
? new object?[] { eventName, reqBody } ? [eventName, reqBody]
: new object?[] { eventName, JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption) }); : [eventName, JsonSerializer.Deserialize(reqBody, pt, SimApiUtil.JsonOption)]);
} }
else else
{ {
@@ -52,6 +54,7 @@ public partial class Synapse
})) }))
.ToList(); .ToList();
await Task.WhenAll(tasks); await Task.WhenAll(tasks);
});
}; };
SubEventServerTopic(); SubEventServerTopic();
} }
+5 -5
View File
@@ -1,20 +1,19 @@
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;
using System.Collections.Concurrent;
namespace SimApi; namespace SimApi;
public partial class Synapse public partial class Synapse
{ {
private Dictionary<string, TaskCompletionSource<string>> ResponseCompletionSources { get; } = new(); private ConcurrentDictionary<string, TaskCompletionSource<string>> ResponseCompletionSources { get; } = new();
private string EventClientTopicPrefix => $"{Options.SysName}/{Options.AppName}/rpc/client/{Options.AppId}/"; private string EventClientTopicPrefix => $"{Options.SysName}/{Options.AppName}/rpc/client/{Options.AppId}/";
@@ -27,7 +26,7 @@ public partial class Synapse
var messageId = e.ApplicationMessage.Topic.Replace(EventClientTopicPrefix, string.Empty); var messageId = e.ApplicationMessage.Topic.Replace(EventClientTopicPrefix, string.Empty);
if (!ResponseCompletionSources.TryGetValue(messageId, out var tcs)) return Task.CompletedTask; if (!ResponseCompletionSources.TryGetValue(messageId, out var tcs)) return Task.CompletedTask;
tcs.SetResult(reqBody); tcs.SetResult(reqBody);
ResponseCompletionSources.Remove(messageId); ResponseCompletionSources.Remove(messageId, out _);
return Task.CompletedTask; return Task.CompletedTask;
}; };
SubRpcClientTopic(); SubRpcClientTopic();
@@ -43,6 +42,7 @@ public partial class Synapse
private string? FireRpc(string app, string action, object? param, Dictionary<string, string>? headers = null, private string? FireRpc(string app, string action, object? param, Dictionary<string, string>? headers = null,
int? timeout = null) int? timeout = null)
{ {
// 移除锁语句
string paramJson; string paramJson;
if (param is string strParam) if (param is string strParam)
{ {
@@ -56,7 +56,7 @@ public partial class Synapse
var topic = $"{Options.SysName}/{app}/rpc/server/{action}"; var topic = $"{Options.SysName}/{app}/rpc/server/{action}";
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.TryAdd(messageId, tcs);
var messageBuilder = new MqttApplicationMessageBuilder() var messageBuilder = new MqttApplicationMessageBuilder()
.WithTopic(topic) .WithTopic(topic)
.WithPayload(paramJson) .WithPayload(paramJson)
+10 -6
View File
@@ -20,9 +20,11 @@ public partial class Synapse
private void RunRpcServer() private void RunRpcServer()
{ {
Client!.ApplicationMessageReceivedAsync += e => Client!.ApplicationMessageReceivedAsync += async e =>
{ {
if (!e.ApplicationMessage.Topic.StartsWith(RpcServerTopicPrefix)) return Task.CompletedTask; await Task.Run(() =>
{
if (!e.ApplicationMessage.Topic.StartsWith(RpcServerTopicPrefix)) return;
var reqBody = e.ApplicationMessage.ConvertPayloadToString(); var reqBody = e.ApplicationMessage.ConvertPayloadToString();
var action = e.ApplicationMessage.Topic.Replace(RpcServerTopicPrefix, string.Empty); var action = e.ApplicationMessage.Topic.Replace(RpcServerTopicPrefix, string.Empty);
var appInfo = e.ApplicationMessage.ResponseTopic.Split(","); var appInfo = e.ApplicationMessage.ResponseTopic.Split(",");
@@ -58,7 +60,10 @@ public partial class Synapse
var pt2 = mt.GetParameters()[0].ParameterType; var pt2 = mt.GetParameters()[0].ParameterType;
var param2 = pt2 == typeof(string) var param2 = pt2 == typeof(string)
? [reqBody] ? [reqBody]
: new[] { JsonSerializer.Deserialize(reqBody, pt2, SimApiUtil.JsonOption), headerData }; : new[]
{
JsonSerializer.Deserialize(reqBody, pt2, SimApiUtil.JsonOption), headerData
};
ret = mt.Invoke(callClass, param2); ret = mt.Invoke(callClass, param2);
break; break;
default: default:
@@ -98,13 +103,12 @@ public partial class Synapse
.WithPayload(returnJson) .WithPayload(returnJson)
.WithRetainFlag(false) .WithRetainFlag(false)
.Build(); .Build();
if (!Client.IsConnected) return Task.CompletedTask; if (!Client.IsConnected) return;
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}",
appInfo[2], action, Options.AppName, appInfo[0], returnJson); appInfo[2], action, Options.AppName, appInfo[0], returnJson);
});
return Task.CompletedTask;
}; };
SubRpcServerTopic(); SubRpcServerTopic();
} }