//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在RRQMCore.XREF命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using RRQMCore.ByteManager; using RRQMCore.Exceptions; using RRQMCore.Run; using RRQMSocket.Http; using RRQMSocket.RPC.RRQMRPC; using System; using System.Text; namespace RRQMSocket.RPC.JsonRpc { /// /// JsonRPC客户端 /// public class JsonRPCClient : TcpClient, IJsonRPCClient { private JsonFormatConverter jsonFormatConverter; private JsonRpcProtocolType protocolType; private RRQMWaitHandle waitHandle; /// /// 构造函数 /// public JsonRPCClient() { waitHandle = new RRQMWaitHandle(); } /// /// Json格式化器 /// public JsonFormatConverter JsonFormatConverter => jsonFormatConverter; /// /// 协议类型 /// public JsonRpcProtocolType ProtocolType { get { return protocolType; } } /// /// RPC调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// /// public T Invoke(string method, InvokeOption invokeOption, ref object[] parameters, Type[] types) { JsonRpcWaitContext context = new JsonRpcWaitContext(); WaitData waitData = this.waitHandle.GetWaitData(context); ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength); if (invokeOption == null) { invokeOption = InvokeOption.WaitInvoke; } try { JsonRequestContext requestContext = new JsonRequestContext(); requestContext.jsonrpc = "2.0"; requestContext.@params = parameters; requestContext.method = method; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { requestContext.id = context.Sign.ToString(); } switch (this.protocolType) { case JsonRpcProtocolType.Tcp: { byteBlock.Write(Encoding.UTF8.GetBytes(jsonFormatConverter.Serialize(requestContext))); break; } case JsonRpcProtocolType.Http: { HttpRequest httpRequest = new HttpRequest(); httpRequest.Method = "POST"; httpRequest.FromJson(jsonFormatConverter.Serialize(requestContext)); httpRequest.Build(byteBlock); } break; } this.Send(byteBlock); } catch (Exception ex) { throw ex; } finally { byteBlock.Dispose(); } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: case FeedbackType.WaitSend: { this.waitHandle.Destroy(waitData); return default; } case FeedbackType.WaitInvoke: { waitData.Wait(invokeOption.WaitTime * 1000); JsonRpcWaitContext resultContext = (JsonRpcWaitContext)waitData.WaitResult; this.waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new RRQMTimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RRQMRPCException(resultContext.error.message); } try { return (T)this.jsonFormatConverter.Deserialize(resultContext.ReturnJsonString, typeof(T)); } catch (Exception ex) { throw ex; } } default: return default; } } /// /// RPC调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// public void Invoke(string method, InvokeOption invokeOption, ref object[] parameters, Type[] types) { JsonRpcWaitContext context = new JsonRpcWaitContext(); WaitData waitData = this.waitHandle.GetWaitData(context); ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength); if (invokeOption == null) { invokeOption = InvokeOption.WaitInvoke; } try { JsonRequestContext requestContext = new JsonRequestContext(); requestContext.jsonrpc = "2.0"; requestContext.@params = parameters; requestContext.method = method; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { requestContext.id = context.Sign.ToString(); } switch (this.protocolType) { case JsonRpcProtocolType.Tcp: { byteBlock.Write(Encoding.UTF8.GetBytes(jsonFormatConverter.Serialize(requestContext))); break; } case JsonRpcProtocolType.Http: { HttpRequest httpRequest = new HttpRequest(); httpRequest.Method = "POST"; httpRequest.FromJson(jsonFormatConverter.Serialize(requestContext)); httpRequest.Build(byteBlock); } break; } this.Send(byteBlock); } catch (Exception ex) { throw ex; } finally { byteBlock.Dispose(); } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: case FeedbackType.WaitSend: { this.waitHandle.Destroy(waitData); return; } case FeedbackType.WaitInvoke: { waitData.Wait(invokeOption.WaitTime * 1000); JsonRpcWaitContext resultContext = (JsonRpcWaitContext)waitData.WaitResult; this.waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new RRQMTimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RRQMRPCException(resultContext.error.message); } return; } default: return; } } /// /// RPC调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// public void Invoke(string method, InvokeOption invokeOption, params object[] parameters) { this.Invoke(method, invokeOption, ref parameters, null); } /// /// RPC调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// public T Invoke(string method, InvokeOption invokeOption, params object[] parameters) { return this.Invoke(method, invokeOption, ref parameters, null); } /// /// 处理数据 /// /// /// protected override void HandleReceivedData(ByteBlock byteBlock, object obj) { switch (this.protocolType) { case JsonRpcProtocolType.Tcp: { string jsonString = Encoding.UTF8.GetString(byteBlock.Buffer, 0, byteBlock.Len); JsonResponseContext responseContext = (JsonResponseContext)this.jsonFormatConverter.Deserialize(jsonString, typeof(JsonResponseContext)); if (responseContext != null) { JsonRpcWaitContext waitContext = new JsonRpcWaitContext(); waitContext.Status = 1; waitContext.Sign = int.Parse(responseContext.id); waitContext.error = responseContext.error; waitContext.ReturnJsonString = responseContext.result == null ? null : responseContext.result.ToString(); this.waitHandle.SetRun(waitContext); } break; } case JsonRpcProtocolType.Http: { HttpResponse httpResponse = (HttpResponse)obj; JsonResponseContext responseContext = (JsonResponseContext)this.jsonFormatConverter.Deserialize(httpResponse.Body, typeof(JsonResponseContext)); if (responseContext != null) { JsonRpcWaitContext waitContext = new JsonRpcWaitContext(); waitContext.Status = 1; waitContext.Sign = int.Parse(responseContext.id); waitContext.error = responseContext.error; waitContext.ReturnJsonString = responseContext.result == null ? null : responseContext.result.ToString(); this.waitHandle.SetRun(waitContext); } break; } } } /// /// 载入配置 /// /// protected override void LoadConfig(TcpClientConfig clientConfig) { base.LoadConfig(clientConfig); this.protocolType = (JsonRpcProtocolType)clientConfig.GetValue(JsonRPCClientConfig.ProtocolTypeProperty); switch (this.protocolType) { case JsonRpcProtocolType.Tcp: this.SetDataHandlingAdapter(new TerminatorDataHandlingAdapter(this.bufferLength, "\r\n")); break; case JsonRpcProtocolType.Http: this.SetDataHandlingAdapter(new HttpDataHandlingAdapter(this.bufferLength, HttpType.Client)); break; } this.jsonFormatConverter = (JsonFormatConverter)clientConfig.GetValue(JsonRPCClientConfig.JsonFormatConverterProperty); } } }