From 6fa046d2a480a42e53ab0e14348df5d3fa6dac6e Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Mon, 18 Oct 2021 10:07:11 +0800 Subject: [PATCH 1/2] =?UTF-8?q?1=E3=80=81WithMetadata=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20IEnumerable=20=E6=8E=A5=E5=8F=A3=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0,=20=E6=96=B9=E4=BE=BF=E8=B0=83=E7=94=A8=202=E3=80=81J?= =?UTF-8?q?son=E5=BA=8F=E5=88=97=E5=8C=96=E5=8F=98=E6=9B=B4=E4=B8=BA=20Utf?= =?UTF-8?q?8Json=E3=80=82=E5=9B=A0=E4=B8=BA=E5=9C=A8System.Text.Json?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E5=8C=96Message=20WithMetadata=20=E6=97=B6?= =?UTF-8?q?=E4=BC=9A=E5=B4=A9=E6=BA=83=E3=80=82=203=E3=80=81examples/Progr?= =?UTF-8?q?am.cs=E5=A2=9E=E5=8A=A0=E6=89=93=E5=8D=B0=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Client.cs | 3 +- Client/WithMetadata.cs | 29 ++++++++------ Shared/Codecs/Serializer/JsonSerializer.cs | 26 ++++++------ Shared/rpcx.net.Shared.csproj | 1 + examples/Program.cs | 46 ++++++++++++++++------ 5 files changed, 65 insertions(+), 40 deletions(-) diff --git a/Client/Client.cs b/Client/Client.cs index fc07008..95576a0 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -5,12 +5,10 @@ using rpcx.net.Client.Generator; using rpcx.net.Shared.Codecs; using rpcx.net.Shared.Protocol; -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Net; using System.Net.Security; -using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -97,6 +95,7 @@ public bool Connect(string network, string address) { public async Task Go(string servicePath, string serviceMethod, TArgs args, CancellationToken cancellationToken = default) { var header = Header.NewRequest(_option.Types); + var msg = new Message(header) { ServicePath = servicePath, ServiceMethod = serviceMethod, diff --git a/Client/WithMetadata.cs b/Client/WithMetadata.cs index 95edb93..eae88c9 100644 --- a/Client/WithMetadata.cs +++ b/Client/WithMetadata.cs @@ -1,24 +1,31 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; -namespace rpcx.net.Client -{ - public abstract class WithMetadata - { +namespace rpcx.net.Client { + + // 增加 IEnumerable 接口实现, 方便调用 + + public abstract class WithMetadata : IEnumerable> { internal protected Dictionary _metadata; - public virtual string this[string k] - { - get - { + public virtual string this[string k] { + get { if (_metadata != null && _metadata.TryGetValue(k, out var v)) return v; return null; } - set - { + set { if (_metadata is null) _metadata = new Dictionary(10); _metadata[k] = value; } } + + public IEnumerator> GetEnumerator() { + return _metadata.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() { + return _metadata.GetEnumerator(); + } } } diff --git a/Shared/Codecs/Serializer/JsonSerializer.cs b/Shared/Codecs/Serializer/JsonSerializer.cs index ec97964..c506978 100644 --- a/Shared/Codecs/Serializer/JsonSerializer.cs +++ b/Shared/Codecs/Serializer/JsonSerializer.cs @@ -1,28 +1,24 @@ using System; -namespace rpcx.net.Shared.Codecs.Serializer -{ - public class JsonSerializer : ISerializer - { +namespace rpcx.net.Shared.Codecs.Serializer { + public class JsonSerializer : ISerializer { private static JsonSerializer _default; - public static JsonSerializer Default - { - get - { + public static JsonSerializer Default { + get { if (_default is null) _default = new JsonSerializer(); return _default; } } - public object Deserialize(Type type, ReadOnlyMemory bytes) - { - var json = System.Text.Encoding.UTF8.GetString(bytes.ToArray()); - return System.Text.Json.JsonSerializer.Deserialize(json, type); + public object Deserialize(Type type, ReadOnlyMemory bytes) { + return Utf8Json.JsonSerializer.NonGeneric.Deserialize(type, bytes.ToArray()); } - //System.Text.Json.JsonSerializer.Deserialize(bytes.Span, type); - public byte[] Serialize(object value) => - System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(value); + + // 替换成 Utf8Json 序列化 + // 因为 在序列化 Message WithMetadata 时, System.Text.Json 会崩溃 + + public byte[] Serialize(object value) => Utf8Json.JsonSerializer.Serialize(value); } } diff --git a/Shared/rpcx.net.Shared.csproj b/Shared/rpcx.net.Shared.csproj index d5bc93f..c5420a3 100644 --- a/Shared/rpcx.net.Shared.csproj +++ b/Shared/rpcx.net.Shared.csproj @@ -18,6 +18,7 @@ + diff --git a/examples/Program.cs b/examples/Program.cs index b7bd47b..77c11cd 100644 --- a/examples/Program.cs +++ b/examples/Program.cs @@ -1,15 +1,16 @@ using rpcx.net.Client; +using rpcx.net.Shared.Protocol; using System; using System.IO; using System.Security.Cryptography.X509Certificates; namespace examples { - public class Args { + public class Args : WithMetadata { public long A { get; set; } public long B { get; set; } } - public class Reply { + public class Reply : WithMetadata { public long C { get; set; } } @@ -24,25 +25,46 @@ static void Main(string[] args) { using var clientCert = new X509Certificate2(pfx); var c = new Client(new Option() { - ClienetCert = clientCert, // 客户端证书 - TargetHost = "01-matrix", // 如果同时客户端证书, 则该参数无效 - Types = rpcx.net.Shared.Protocol.Header.eType.MessagePack, // | rpcx.net.Shared.Protocol.Header.eType.Gzip, + //ClienetCert = clientCert, // 客户端证书 + // TargetHost = "01-matrix", // 如果同时客户端证书, 则该参数无效 + Types = Header.eType.MessagePack, // | rpcx.net.Shared.Protocol.Header.eType.Gzip, }); c.Connect("tcp", "127.0.0.1:8972"); c.OnServerMessage += C_OnServerMessage; var ar = new Args() { A = 10, B = 20 }; - var t1 = c.Go("Arith", "Mul", ar); + // Metadata + ar["ab"] = "1"; + ar["cd"] = "2"; + var t1 = c.Go("Arith", "Mul", ar).Result; + ar = new Args() { A = 3, B = 5 }; - var t2 = c.Go("Arith", "Mul", ar); + // Metadata + ar["cd"] = "3"; + ar["ef"] = "4"; + var t2 = c.Go("Arith", "Mul", ar).Result; + ar = new Args() { A = 7, B = 8 }; - var t3 = c.Go("Arith", "Mul", ar); - var r1 = t1.Result; - var r2 = t2.Result; - var r3 = t3.Result; + // Metadata + ar["gh"] = "5"; + ar["ij"] = "6"; + var t3 = c.Go("Arith", "Mul", ar).Result; + + PrintReply(t1, t2, t3); + + Console.WriteLine("Press Any Key to exit..."); + Console.ReadKey(); + } - Console.ReadLine(); + private static void PrintReply(params Reply[] replies) { + foreach (var reply in replies) { + foreach (var k in reply) { + Console.WriteLine($"Key={k.Key}, Value={k.Value}"); + } + Console.WriteLine($"Reply={reply.C}"); + Console.WriteLine(); + } } private static void C_OnServerMessage(object sender, rpcx.net.Shared.Protocol.Message msg) { From bd2a8ed11df2a05f6781a2581a7e07c258ee1364 Mon Sep 17 00:00:00 2001 From: 13981712066 Date: Mon, 8 Nov 2021 13:04:12 +0800 Subject: [PATCH 2/2] =?UTF-8?q?1,=20=E7=A7=BB=E9=99=A4WithMetadata.cs?= =?UTF-8?q?=E3=80=82=202,=20=E5=A2=9E=E5=8A=A0=20Context.cs,=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E4=B8=8A=E4=B8=8B=E6=96=87=E5=9F=BA=E6=9C=AC=E7=B1=BB?= =?UTF-8?q?=E3=80=82=203,=20=E4=BF=AE=E6=94=B9IRPCClient=20->=20Go,=20?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E4=B8=8A=E4=B8=8B=E6=96=87=E5=8F=82=E6=95=B0?= =?UTF-8?q?=204,=20TaskCompletionSource.cs=20=E4=B8=AD,=20=E5=B0=86Message?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E8=B5=B7=E6=9D=A5=205,=20Client.cs=20->=20Ch?= =?UTF-8?q?annelRead0=20->=20=E5=A2=9E=E5=8A=A0=E5=AF=B9=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E4=B8=8A=E4=B8=8B=E6=96=87=E5=A4=84=E7=90=86?= =?UTF-8?q?=E3=80=82=206,=20Program.cs=20=E4=B8=AD,=20=E4=BF=AE=E8=AE=A2?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/Client.cs | 36 +++++++-- Client/IRPCClient.cs | 9 +-- Client/TaskCompletionSource.cs | 16 ++-- Client/WithMetadata.cs | 31 -------- Shared/Codecs/RpcxMessageDecoder.cs | 34 ++++---- Shared/Codecs/RpcxMessageEncoder.cs | 26 +++--- Shared/Codecs/Serializer/JsonSerializer.cs | 2 +- Shared/Context.cs | 87 +++++++++++++++++++++ Shared/Protocol/Message.cs | 10 ++- examples/Program.cs | 51 ++++++------ examples/conf/encrypt/ca.pem | 15 ++++ examples/conf/encrypt/client.key | 8 ++ examples/conf/encrypt/client.pem | 14 ++++ examples/conf/normal/ca.pem | 15 ++++ examples/conf/normal/client.csr | 10 +++ examples/conf/normal/client.key | 8 ++ examples/conf/normal/client.pem | 14 ++++ examples/conf/normal/client.pfx | Bin 0 -> 1078 bytes 18 files changed, 278 insertions(+), 108 deletions(-) delete mode 100644 Client/WithMetadata.cs create mode 100644 Shared/Context.cs create mode 100644 examples/conf/encrypt/ca.pem create mode 100644 examples/conf/encrypt/client.key create mode 100644 examples/conf/encrypt/client.pem create mode 100644 examples/conf/normal/ca.pem create mode 100644 examples/conf/normal/client.csr create mode 100644 examples/conf/normal/client.key create mode 100644 examples/conf/normal/client.pem create mode 100644 examples/conf/normal/client.pfx diff --git a/Client/Client.cs b/Client/Client.cs index 95576a0..5345fa6 100644 --- a/Client/Client.cs +++ b/Client/Client.cs @@ -3,6 +3,7 @@ using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using rpcx.net.Client.Generator; +using rpcx.net.Shared; using rpcx.net.Shared.Codecs; using rpcx.net.Shared.Protocol; using System.Collections.Concurrent; @@ -93,18 +94,19 @@ public bool Connect(string network, string address) { return true; } - public async Task Go(string servicePath, string serviceMethod, TArgs args, CancellationToken cancellationToken = default) { + public async Task Go(IContext ctx, string servicePath, string serviceMethod, TArgs args, CancellationToken cancellationToken = default) { var header = Header.NewRequest(_option.Types); - + var msg = new Message(header) { ServicePath = servicePath, ServiceMethod = serviceMethod, - Metadata = args is WithMetadata a ? a._metadata : null, + Context = ctx, Payload = GetSerializer(header.SerializeType).Serialize(args), }; msg.Header.Seq = IdGen.Next(); - var tcs = new TaskCompletionSource(typeof(TReply)); + // 附加原始调用参数数据 + var tcs = new TaskCompletionSource(typeof(TReply), msg); _pending.TryAdd(msg.Header.Seq, tcs); _ = _chan.WriteAndFlushAsync(msg); return (TReply)await tcs.Task.ConfigureAwait(false); @@ -138,12 +140,34 @@ protected override void ChannelRead0(IChannelHandlerContext ctx, Message msg) { tcs.TrySetResult(msg.Payload); } else { var obj = GetSerializer(msg.Header.SerializeType).Deserialize(tcs.ResultType, msg.Payload); - if (obj is WithMetadata o) - o._metadata = msg.Metadata; + + // 使用附加数据处理 + //if (obj is WithMetadata o) + // o._metadata = msg.Metadata; + + var msgCtx = msg.Context; + if (msgCtx == null) { + return; + } + var tcsMsg = tcs.Message; + if (tcsMsg == null) { + return; + } + var tcsCtx = tcsMsg.Context; + if (tcsCtx == null) { + return; + } + while (msgCtx != null) { + var key = msgCtx.Key(); + tcsCtx.SetValue(key, msgCtx.Value(key)); + msgCtx = msgCtx.Parent(); + } + tcs.TrySetResult(obj); } } } + #endregion } } diff --git a/Client/IRPCClient.cs b/Client/IRPCClient.cs index 764cb30..afb59d7 100644 --- a/Client/IRPCClient.cs +++ b/Client/IRPCClient.cs @@ -1,16 +1,15 @@ using DotNetty.Transport.Channels; -using System; using System.Net; using System.Threading; using rpcx.net.Shared.Protocol; using System.Threading.Tasks; +using rpcx.net.Shared; -namespace rpcx.net.Client -{ - public interface IRPCClient +namespace rpcx.net.Client { + public interface IRPCClient { bool Connect(string network, string address); - Task Go(string servicePath, string serviceMethod, TArgs args, CancellationToken cancellationToken = default); + Task Go(IContext ctx, string servicePath, string serviceMethod, TArgs args, CancellationToken cancellationToken = default); Task SendRaw(Message message, CancellationToken cancellationToken = default); void Close(); diff --git a/Client/TaskCompletionSource.cs b/Client/TaskCompletionSource.cs index b8309f9..dbbf962 100644 --- a/Client/TaskCompletionSource.cs +++ b/Client/TaskCompletionSource.cs @@ -1,14 +1,16 @@ -using System; +using rpcx.net.Shared.Protocol; +using System; using System.Threading.Tasks; -namespace rpcx.net.Client -{ - public class TaskCompletionSource : TaskCompletionSource - { +namespace rpcx.net.Client { + public class TaskCompletionSource : TaskCompletionSource { public Type ResultType { get; } - public TaskCompletionSource(Type resultType) : this() - { + // 增加原始参数数据 + public Message Message { get; } + + public TaskCompletionSource(Type resultType, Message message) : this() { + Message = message; ResultType = resultType; } diff --git a/Client/WithMetadata.cs b/Client/WithMetadata.cs deleted file mode 100644 index eae88c9..0000000 --- a/Client/WithMetadata.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - -namespace rpcx.net.Client { - - // 增加 IEnumerable 接口实现, 方便调用 - - public abstract class WithMetadata : IEnumerable> { - internal protected Dictionary _metadata; - public virtual string this[string k] { - get { - if (_metadata != null && _metadata.TryGetValue(k, out var v)) - return v; - return null; - } - set { - if (_metadata is null) - _metadata = new Dictionary(10); - _metadata[k] = value; - } - } - - public IEnumerator> GetEnumerator() { - return _metadata.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() { - return _metadata.GetEnumerator(); - } - } -} diff --git a/Shared/Codecs/RpcxMessageDecoder.cs b/Shared/Codecs/RpcxMessageDecoder.cs index b296397..8983931 100644 --- a/Shared/Codecs/RpcxMessageDecoder.cs +++ b/Shared/Codecs/RpcxMessageDecoder.cs @@ -6,17 +6,13 @@ using System.Text; using static rpcx.net.Shared.Utils; -namespace rpcx.net.Shared.Codecs -{ - public class RpcxMessageDecoder : LengthFieldBasedFrameDecoder - { +namespace rpcx.net.Shared.Codecs { + public class RpcxMessageDecoder : LengthFieldBasedFrameDecoder { public RpcxMessageDecoder(int maxFrameLength = 10240) : base(maxFrameLength, 12, 4) { } - protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) - { - if (base.Decode(context, input) is IByteBuffer buf) - { + protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output) { + if (base.Decode(context, input) is IByteBuffer buf) { int nLen; var byHeader = new byte[16]; @@ -34,10 +30,9 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input Dictionary metadata = null; if (0 != (nLen = buf.ReadInt())) metadata = DecodeMetadata(buf, nLen, Encoding.UTF8); - + byte[] payload = null; - if (0 != (nLen = buf.ReadInt())) - { + if (0 != (nLen = buf.ReadInt())) { payload = new byte[nLen]; buf.ReadBytes(payload, 0, nLen); var compressor = GetCompressor(header.CompressType); @@ -45,23 +40,26 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input payload = compressor.Unzip(payload); } - output.Add(new Message(header) { + // 处理 Message + var msg = new Message(header) { ServicePath = servicePath, ServiceMethod = serviceMethod, - Metadata = metadata, Payload = payload, - }); + }; + // todo: 现在只处理 ResMetaDataKey, 以后可能会出现其他的上下文处理 + if (metadata != null) { + msg.Context = Context.WithValue(msg.Context, Context.ResMetaDataKey, metadata); + }; + output.Add(msg); } } - protected Dictionary DecodeMetadata(IByteBuffer buf, int lenght, Encoding encoding) - { + protected Dictionary DecodeMetadata(IByteBuffer buf, int lenght, Encoding encoding) { var res = new Dictionary(10); var endIdx = buf.ReaderIndex + lenght; int len; string k, v; - while(endIdx > buf.ReaderIndex) - { + while (endIdx > buf.ReaderIndex) { len = buf.ReadInt(); k = buf.ReadString(len, encoding); len = buf.ReadInt(); diff --git a/Shared/Codecs/RpcxMessageEncoder.cs b/Shared/Codecs/RpcxMessageEncoder.cs index 894c1d5..a48021c 100644 --- a/Shared/Codecs/RpcxMessageEncoder.cs +++ b/Shared/Codecs/RpcxMessageEncoder.cs @@ -6,19 +6,15 @@ using System.Text; using static rpcx.net.Shared.Utils; -namespace rpcx.net.Shared.Codecs -{ - public class RpcxMessageEncoder : MessageToByteEncoder - { - protected override void Encode(IChannelHandlerContext context, Message message, IByteBuffer output) - { +namespace rpcx.net.Shared.Codecs { + public class RpcxMessageEncoder : MessageToByteEncoder { + protected override void Encode(IChannelHandlerContext context, Message message, IByteBuffer output) { var byHeader = message.Header.GetBytes(); var byServicePath = Encoding.UTF8.GetBytes(message.ServicePath); var byServiceMethod = Encoding.UTF8.GetBytes(message.ServiceMethod); //var byMetadata = message.Metadata.GetBytes(); var bufMetadata = context.Allocator.Buffer(); - var nLenMetadata = EncodeMetadata(bufMetadata, message.Metadata, Encoding.UTF8); - + var nLenMetadata = EncodeMetadata(bufMetadata, message.Context, Encoding.UTF8); var compressor = GetCompressor(message.Header.CompressType); var byPayload = compressor is null ? message.Payload : compressor.Zip(message.Payload); @@ -37,13 +33,17 @@ protected override void Encode(IChannelHandlerContext context, Message message, output.WriteBytes(byPayload); } - protected int EncodeMetadata(IByteBuffer buf, Dictionary metadata, Encoding encoding) - { - if (metadata is null) return 0; + protected int EncodeMetadata(IByteBuffer buf, IContext ctx, Encoding encoding) { + if (ctx == null) { return 0; } + + // todo: 如果ReqMetaDataKey对应的类型不是IDictionary, 应当怎样处理 + var metadata = ctx.Value(Context.ReqMetaDataKey) as IDictionary; + if (metadata == null) { return 0; } + var startIdx = buf.WriterIndex; + byte[] k, v; - foreach(var kv in metadata) - { + foreach (var kv in metadata) { k = encoding.GetBytes(kv.Key); v = encoding.GetBytes(kv.Value); buf.WriteInt(k.Length); diff --git a/Shared/Codecs/Serializer/JsonSerializer.cs b/Shared/Codecs/Serializer/JsonSerializer.cs index c506978..33ab322 100644 --- a/Shared/Codecs/Serializer/JsonSerializer.cs +++ b/Shared/Codecs/Serializer/JsonSerializer.cs @@ -15,7 +15,7 @@ public object Deserialize(Type type, ReadOnlyMemory bytes) { return Utf8Json.JsonSerializer.NonGeneric.Deserialize(type, bytes.ToArray()); } - + // https://michaelscodingspot.com/the-battle-of-c-to-json-serializers-in-net-core-3/ // 替换成 Utf8Json 序列化 // 因为 在序列化 Message WithMetadata 时, System.Text.Json 会崩溃 diff --git a/Shared/Context.cs b/Shared/Context.cs new file mode 100644 index 0000000..ca3ac8a --- /dev/null +++ b/Shared/Context.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace rpcx.net.Shared { + public interface IContext { + object Key(); + object Value(object key); + void SetValue(object key, object val); + + IContext Parent(); + IContext FindParent(object key); + } + + public sealed class Context { + /// + /// ReqMetaDataKey is used to set metatdata in context of requests. + /// refrence: rpcx -> ReqMetaDataKey + /// + public const string ReqMetaDataKey = "__req_metadata"; + + /// + /// ResMetaDataKey is used to set metatdata in context of responses. + /// refrence: rpcx -> ResMetaDataKey + /// + public const string ResMetaDataKey = "__res_metadata"; + + public static IContext WithValue(IContext parent, object key, object val = null) { + return new valueCtx { + _parent = parent, + _key = key, + _val = val + }; + } + + /// + /// 设置 medadata + /// + /// + /// Medatada + /// + public static IContext WithMetadata(IContext parent, IDictionary val) { + return WithValue(parent, ReqMetaDataKey, val); + } + } + + class valueCtx : IContext { + internal IContext _parent; + + internal object _key; + internal object _val; + + public object Key() => _key; + + public object Value(object key) { + if (_key == key) { + return _val; + } + if (_parent == null) { + return null; + } + return _parent.Value(key); + } + + public void SetValue(object key, object val) { + var ctx = FindParent(key) as valueCtx; + if (ctx == null) { + throw new Exception($"当前对象上下文中,无法找到 [Key = {key} ] 对应的节点。"); + } + ctx._val = val; + } + + public IContext Parent() => _parent; + + public IContext FindParent(object key) { + if (this._key == key) { + return this; + } + + var parent = this._parent; + if (parent == null) { + this._parent = Context.WithValue(null, key); + return this._parent; + } + return parent.FindParent(key); + } + } +} diff --git a/Shared/Protocol/Message.cs b/Shared/Protocol/Message.cs index fcea318..e56be78 100644 --- a/Shared/Protocol/Message.cs +++ b/Shared/Protocol/Message.cs @@ -1,13 +1,15 @@ -using System.Collections.Generic; - -namespace rpcx.net.Shared.Protocol +namespace rpcx.net.Shared.Protocol { public class Message { public Header Header { get; set; } public string ServicePath { get; set; } public string ServiceMethod { get; set; } - public Dictionary Metadata { get; set; } + + // 使用 Contex t替代 + // public Dictionary Metadata { get; set; } + public IContext Context { get; set; } + public byte[] Payload { get; set; } //public byte[] Data { get; set; } diff --git a/examples/Program.cs b/examples/Program.cs index 77c11cd..79cd4c0 100644 --- a/examples/Program.cs +++ b/examples/Program.cs @@ -1,16 +1,19 @@ using rpcx.net.Client; +using rpcx.net.Shared; using rpcx.net.Shared.Protocol; using System; +using System.Collections.Generic; using System.IO; using System.Security.Cryptography.X509Certificates; +using System.Text; namespace examples { - public class Args : WithMetadata { + public class Args { public long A { get; set; } public long B { get; set; } } - public class Reply : WithMetadata { + public class Reply { public long C { get; set; } } @@ -33,38 +36,40 @@ static void Main(string[] args) { c.Connect("tcp", "127.0.0.1:8972"); c.OnServerMessage += C_OnServerMessage; + var md = new Dictionary { { "ab", "1" }, { "cd", "2" } }; + + var ctx1 = Context.WithMetadata(null, md); var ar = new Args() { A = 10, B = 20 }; - // Metadata - ar["ab"] = "1"; - ar["cd"] = "2"; - var t1 = c.Go("Arith", "Mul", ar).Result; + var t1 = c.Go(ctx1, "Arith", "Mul", ar).Result; + PrintReply(ctx1, t1); + var ctx2 = Context.WithMetadata(null, md); ar = new Args() { A = 3, B = 5 }; - // Metadata - ar["cd"] = "3"; - ar["ef"] = "4"; - var t2 = c.Go("Arith", "Mul", ar).Result; + var t2 = c.Go(ctx2, "Arith", "Mul", ar).Result; + PrintReply(ctx2, t2); + var ctx3 = Context.WithMetadata(null, md); ar = new Args() { A = 7, B = 8 }; - // Metadata - ar["gh"] = "5"; - ar["ij"] = "6"; - var t3 = c.Go("Arith", "Mul", ar).Result; - - PrintReply(t1, t2, t3); + var t3 = c.Go(ctx3, "Arith", "Mul", ar).Result; + PrintReply(ctx3, t3); Console.WriteLine("Press Any Key to exit..."); Console.ReadKey(); } - private static void PrintReply(params Reply[] replies) { - foreach (var reply in replies) { - foreach (var k in reply) { - Console.WriteLine($"Key={k.Key}, Value={k.Value}"); - } - Console.WriteLine($"Reply={reply.C}"); - Console.WriteLine(); + private static void PrintReply(IContext ctx, Reply reply) { + Console.WriteLine("-----------------------------------------------------"); + while (ctx != null) { + var key = ctx.Key(); + var val = ctx.Value(key); + var json = Encoding.UTF8.GetString(Utf8Json.JsonSerializer.Serialize(val)); + Console.WriteLine($"Key = {key} Value = {json}"); + + ctx = ctx.Parent(); } + + Console.WriteLine($"Reply = {reply.C}"); + Console.WriteLine(); } private static void C_OnServerMessage(object sender, rpcx.net.Shared.Protocol.Message msg) { diff --git a/examples/conf/encrypt/ca.pem b/examples/conf/encrypt/ca.pem new file mode 100644 index 0000000..67e92bd --- /dev/null +++ b/examples/conf/encrypt/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICUzCCAfmgAwIBAgIUCxeB7USoOo+IVCrXzf5KKkiidUEwCgYIKoZIzj0EAwIw +fzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQHDAJDRDESMBAGA1UE +CgwJMDEtbWF0cml4MQwwCgYDVQQLDANkZXYxEjAQBgNVBAMMCTAxLW1hdHJpeDEg +MB4GCSqGSIb3DQEJARYRcGl5b25nY2FpQDE2My5jb20wHhcNMjEwOTA2MDkxMTE3 +WhcNMzEwOTA0MDkxMTE3WjB/MQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxCzAJ +BgNVBAcMAkNEMRIwEAYDVQQKDAkwMS1tYXRyaXgxDDAKBgNVBAsMA2RldjESMBAG +A1UEAwwJMDEtbWF0cml4MSAwHgYJKoZIhvcNAQkBFhFwaXlvbmdjYWlAMTYzLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPsFqfISZ2JADxDwdAja6KigYYuS +gGkQ9+VSbnP4+3BFAnc6+QvnkN5OtK2QTKX5lMCQA7law2X9g/O3sQthbUijUzBR +MB0GA1UdDgQWBBR81MaB+Z4oebIkMcCNtBWMA4mopjAfBgNVHSMEGDAWgBR81MaB ++Z4oebIkMcCNtBWMA4mopjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gA +MEUCIQCxe1mtjRpZXww/qzTmXAGm2jvLTAk8lkYSnB4LXTusLAIgHgWfezQdAxfG +OGv9GttjiaV5zjiZscTejxxojbB80KA= +-----END CERTIFICATE----- diff --git a/examples/conf/encrypt/client.key b/examples/conf/encrypt/client.key new file mode 100644 index 0000000..6b92baf --- /dev/null +++ b/examples/conf/encrypt/client.key @@ -0,0 +1,8 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,9474D5E7FE1ECA54F2023EB9183ADE99 + +Uqq05Iu4aBLfhMEQunHVuFr21px4IfXsLbOfP5vcCzAvgf6IRXugBf20wyZCFfz2 +F64f62wmKNLDdLK+x+L1LtgTEMfuzxYLAwG1iWqYjFWQpr1qRZE+16ROcBmGFe5B +ZKMW+nH8DsdAywBdDbPti74k5zlLpgSGOu3eyocQviM= +-----END EC PRIVATE KEY----- diff --git a/examples/conf/encrypt/client.pem b/examples/conf/encrypt/client.pem new file mode 100644 index 0000000..034ec59 --- /dev/null +++ b/examples/conf/encrypt/client.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMDCCAdagAwIBAgIUZBYOPOLgAWl2pwtUlQiSeTsqg0UwCgYIKoZIzj0EAwIw +fzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQHDAJDRDESMBAGA1UE +CgwJMDEtbWF0cml4MQwwCgYDVQQLDANkZXYxEjAQBgNVBAMMCTAxLW1hdHJpeDEg +MB4GCSqGSIb3DQEJARYRcGl5b25nY2FpQDE2My5jb20wHhcNMjEwOTA4MDA0NzEx +WhcNMzEwOTA2MDA0NzExWjB/MQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxCzAJ +BgNVBAcMAkNEMRIwEAYDVQQKDAkwMS1tYXRyaXgxDDAKBgNVBAsMA2RldjESMBAG +A1UEAwwJMDEtbWF0cml4MSAwHgYJKoZIhvcNAQkBFhFwaXlvbmdjYWlAMTYzLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPr9Buk+BcYVJQ3MwwIcvXhsyWa7 +Yr89CxPu8ms9Uz+tHp557Cpa60PybvZtjtjo5wrFqI5n5CPi2YXQXGDr+zOjMDAu +MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBQGA1UdEQQNMAuCCTAxLW1hdHJpeDAK +BggqhkjOPQQDAgNIADBFAiEAjVPsR3UXxbHCx7MlyLJ9gl6KwqF7BCDVzShxmlBN +0m8CIBAQOoSpGNr0O0zK7+0Vg4JLi57RhymFmgjYohEHNEfX +-----END CERTIFICATE----- diff --git a/examples/conf/normal/ca.pem b/examples/conf/normal/ca.pem new file mode 100644 index 0000000..3086d01 --- /dev/null +++ b/examples/conf/normal/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICUzCCAfmgAwIBAgIUZM+93ao4UIo1XXccZYIAd2R9BLIwCgYIKoZIzj0EAwIw +fzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQHDAJDRDESMBAGA1UE +CgwJMDEtbWF0cml4MQwwCgYDVQQLDANkZXYxEjAQBgNVBAMMCTAxLW1hdHJpeDEg +MB4GCSqGSIb3DQEJARYRcGl5b25nY2FpQDE2My5jb20wHhcNMjEwOTA2MDg1NzU2 +WhcNMzEwOTA0MDg1NzU2WjB/MQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxCzAJ +BgNVBAcMAkNEMRIwEAYDVQQKDAkwMS1tYXRyaXgxDDAKBgNVBAsMA2RldjESMBAG +A1UEAwwJMDEtbWF0cml4MSAwHgYJKoZIhvcNAQkBFhFwaXlvbmdjYWlAMTYzLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDaF67EeiBlpe0iO4rdmu9S8BDmE +z3kzYhcVrBnMsJKSZqtN/QN2o6ZccKCzE1enjvRTPnXTJK6SGfz4Neq0HmWjUzBR +MB0GA1UdDgQWBBTMmFJZFKLwU34LreMW7ostpvk32DAfBgNVHSMEGDAWgBTMmFJZ +FKLwU34LreMW7ostpvk32DAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gA +MEUCIGPJpbR1VAzJgDtdi5XkRX/F3oJ4f7YXN49ySn8p++7cAiEAiyvpEzCVcupL +Mf3q0buRqRvtkz3kXikcgadZkAYUaTY= +-----END CERTIFICATE----- diff --git a/examples/conf/normal/client.csr b/examples/conf/normal/client.csr new file mode 100644 index 0000000..94ca331 --- /dev/null +++ b/examples/conf/normal/client.csr @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBejCCASACAQAwfzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQH +DAJDRDESMBAGA1UECgwJMDEtbWF0cml4MQwwCgYDVQQLDANkZXYxEjAQBgNVBAMM +CTAxLW1hdHJpeDEgMB4GCSqGSIb3DQEJARYRcGl5b25nY2FpQDE2My5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAARW77Nv1nIzb1xGVjxvMNtdYqstN5jN94WI +T30ae4kwRT3BwR8jdOMas7Jo5dFjtcKm4Wx3JmrlLujAX6kvtRxHoD8wPQYJKoZI +hvcNAQkOMTAwLjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAUBgNVHREEDTALggkw +MS1tYXRyaXgwCgYIKoZIzj0EAwIDSAAwRQIgZwvkndTEWfqLdiA5QIwsaD1L/P6R +oBu9RgmLC8dDxU4CIQDBQnA2LQr9ccVQTiMYGmkg3Mk3953OPNUO/6wmeDWkag== +-----END CERTIFICATE REQUEST----- diff --git a/examples/conf/normal/client.key b/examples/conf/normal/client.key new file mode 100644 index 0000000..415e6a2 --- /dev/null +++ b/examples/conf/normal/client.key @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIEcvT/IdAW26yndvgkpVH8j+9jwQXYEQOQYOaaVPv0eZoAoGCCqGSM49 +AwEHoUQDQgAEVu+zb9ZyM29cRlY8bzDbXWKrLTeYzfeFiE99GnuJMEU9wcEfI3Tj +GrOyaOXRY7XCpuFsdyZq5S7owF+pL7UcRw== +-----END EC PRIVATE KEY----- diff --git a/examples/conf/normal/client.pem b/examples/conf/normal/client.pem new file mode 100644 index 0000000..c5fb6ff --- /dev/null +++ b/examples/conf/normal/client.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICMTCCAdagAwIBAgIUTlEyJqA6uv1OV7PI27FwiNNDaLMwCgYIKoZIzj0EAwIw +fzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQHDAJDRDESMBAGA1UE +CgwJMDEtbWF0cml4MQwwCgYDVQQLDANkZXYxEjAQBgNVBAMMCTAxLW1hdHJpeDEg +MB4GCSqGSIb3DQEJARYRcGl5b25nY2FpQDE2My5jb20wHhcNMjEwOTA2MDkwMDQ5 +WhcNMzEwOTA0MDkwMDQ5WjB/MQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0MxCzAJ +BgNVBAcMAkNEMRIwEAYDVQQKDAkwMS1tYXRyaXgxDDAKBgNVBAsMA2RldjESMBAG +A1UEAwwJMDEtbWF0cml4MSAwHgYJKoZIhvcNAQkBFhFwaXlvbmdjYWlAMTYzLmNv +bTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFbvs2/WcjNvXEZWPG8w211iqy03 +mM33hYhPfRp7iTBFPcHBHyN04xqzsmjl0WO1wqbhbHcmauUu6MBfqS+1HEejMDAu +MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBQGA1UdEQQNMAuCCTAxLW1hdHJpeDAK +BggqhkjOPQQDAgNJADBGAiEA4kfMD2txPgt7GRA7ymMYdQXpMUYh5ZlrZYiFtSww +xToCIQD7Kh3g6jQ5MmLFFvAxHhUgaPi/Bf+7jraXGUYX+HEcag== +-----END CERTIFICATE----- diff --git a/examples/conf/normal/client.pfx b/examples/conf/normal/client.pfx new file mode 100644 index 0000000000000000000000000000000000000000..bbe8f1034924c550034f2609b27fd69b4312820f GIT binary patch literal 1078 zcmXqLVliT3WHxAG{=vqn)#lOmotKfFaX}OFOO__)r$FI{22D)Y5mIamnwU-ig^n;W zG61Q)2pL8L88$Ac2|SE!27D|W_J7xY^pO3}!obe7E~8@eZIqXU*W<-mVdr93zx=EQhIU2cKTHTp>y9?#HeI{jO7b| z&?41(tj28a7T+cBT23iu<$QXtxbl9?`d7K{(i&tgzT4&}b<<4ZSlZ&!i_^ZXUbC$J z)6{>93uHnkb9v1OO8CWk7&x9N0te2TRT_4*vG@r~^vh+ZRYFd2a_rs~z8DDwm+?acqxuelkt zuijd8W~Xo0|4rM@tiH5f@LZ&zA%DDB!heNjPv4i+8@x$aU-U;_=ZJgKaWB0UJn!9p zxhDNM{#M8~!jCtm`Qw7Ek}rhjtIfB6$;D=T(<3(BI zUmTNfv`o96{rJ7s>3N^J^_ISguUIg>{h$<)d`AHdb%Lb0swe!?xz3% literal 0 HcmV?d00001