//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在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 // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Collections.Generic; using System.IO; using System.Net.Sockets; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Http; using TouchSocket.Http.WebSockets; using TouchSocket.Rpc.TouchRpc; using TouchSocket.Sockets; namespace TouchSocket.Rpc.JsonRpc { /// /// JsonRpc客户端 /// public class JsonRpcClient : DisposableObject, ITcpClient, IJsonRpcClient { private readonly WaitHandlePool m_waitHandle; private JRPT m_jrpt; /// /// 构造函数 /// public JsonRpcClient() { m_waitHandle = new WaitHandlePool(); } /// /// /// public int BufferLength => Client.BufferLength; /// /// /// public bool CanSend => Client.CanSend; /// /// /// public bool CanSetDataHandlingAdapter => Client.CanSetDataHandlingAdapter; /// /// 内部客户端 /// public ITcpClient Client { get; private set; } /// /// /// public TouchSocketConfig Config => Client.Config; /// /// /// public MessageEventHandler Connected { get => Client.Connected; set => Client.Connected = value; } /// /// /// public ConnectingEventHandler Connecting { get => Client.Connecting; set => Client.Connecting = value; } /// /// /// public IContainer Container => ((IClient)Client).Container; /// /// /// public DataHandlingAdapter DataHandlingAdapter => Client.DataHandlingAdapter; /// /// /// public DisconnectEventHandler Disconnected { get => Client.Disconnected; set => Client.Disconnected = value; } /// public DisconnectEventHandler Disconnecting { get => Client.Disconnecting; set => Client.Disconnecting = value; } /// /// /// public string IP => Client.IP; /// public bool IsClient => Client.IsClient; /// /// 协议类型 /// public JRPT JRPT => m_jrpt; /// /// /// public DateTime LastReceivedTime => Client.LastReceivedTime; /// /// /// public DateTime LastSendTime => Client.LastSendTime; /// /// /// public ILog Logger => Client.Logger; /// /// /// public Socket MainSocket => Client.MainSocket; /// /// /// public Func OnHandleRawBuffer { get => Client.OnHandleRawBuffer; set => Client.OnHandleRawBuffer = value; } /// /// /// public Func OnHandleReceivedData { get => Client.OnHandleReceivedData; set => Client.OnHandleReceivedData = value; } /// /// /// public bool Online => Client.Online; /// /// /// public IPluginsManager PluginsManager => Client.PluginsManager; /// /// /// public int Port => Client.Port; /// /// /// public Protocol Protocol { get => Client.Protocol; set => Client.Protocol = value; } /// /// /// public ReceiveType ReceiveType => Client.ReceiveType; /// /// /// public IPHost RemoteIPHost => Client.RemoteIPHost; /// /// /// public Func TryCanInvoke { get; set; } /// /// /// public bool UsePlugin => Client.UsePlugin; /// /// /// public bool UseSsl => Client.UseSsl; /// /// /// public void Close() { Client.Close(); } /// /// /// public void Close(string msg) { Client.Close(msg); } /// /// /// public ITcpClient Connect(int timeout = 5000) { Client.OnHandleReceivedData = HandleReceivedData; Client.Connect(timeout); return this; } /// /// /// public Task ConnectAsync(int timeout = 5000) { return EasyTask.Run(() => { return Connect(timeout); }); } /// /// /// public void DefaultSend(byte[] buffer, int offset, int length) { Client.DefaultSend(buffer, offset, length); } /// /// /// public Task DefaultSendAsync(byte[] buffer, int offset, int length) { return Client.DefaultSendAsync(buffer, offset, length); } /// /// /// public Stream GetStream() { return Client.GetStream(); } /// /// /// public TValue GetValue(IDependencyProperty dp) { return Client.GetValue(dp); } /// /// /// public void Send(byte[] buffer, int offset, int length) { Client.Send(buffer, offset, length); } /// /// /// public void Send(IRequestInfo requestInfo) { Client.Send(requestInfo); } /// /// /// public void Send(IList> transferBytes) { Client.Send(transferBytes); } /// /// /// public Task SendAsync(byte[] buffer, int offset, int length) { return Client.SendAsync(buffer, offset, length); } /// /// /// public Task SendAsync(IRequestInfo requestInfo) { return Client.SendAsync(requestInfo); } /// /// /// public Task SendAsync(IList> transferBytes) { return Client.SendAsync(transferBytes); } /// /// /// public void SetDataHandlingAdapter(DataHandlingAdapter adapter) { Client.SetDataHandlingAdapter(adapter); } /// /// /// public ITcpClient Setup(TouchSocketConfig config) { m_jrpt = config.GetValue(JsonRpcConfigExtensions.JRPTProperty); switch (m_jrpt) { case JRPT.Http: Client ??= new HttpClient(); break; case JRPT.Websocket: Client ??= new WebSocketClient(); break; case JRPT.Tcp: default: Client ??= new Sockets.TcpClient(); break; } return Client.Setup(config); } /// /// /// public ITcpClient Setup(string ipHost) { TouchSocketConfig config = new TouchSocketConfig(); config.SetRemoteIPHost(new IPHost(ipHost)); return Setup(config); } /// /// /// public DependencyObject SetValue(IDependencyProperty dp, TValue value) { return Client.SetValue(dp, value); } /// /// 处理数据 /// /// /// private bool HandleReceivedData(ByteBlock byteBlock, IRequestInfo requestInfo) { string jsonString = null; switch (m_jrpt) { case JRPT.Http: { HttpResponse httpResponse = (HttpResponse)requestInfo; jsonString = httpResponse.GetBody(); break; } case JRPT.Websocket: { if (requestInfo is WSDataFrame dataFrame && dataFrame.Opcode == WSDataType.Text) { jsonString = dataFrame.ToText(); } break; } case JRPT.Tcp: default: { if (byteBlock == null) { return true; } else { jsonString = byteBlock.ToString(); } break; } } if (string.IsNullOrEmpty(jsonString)) { return true; } try { if (jsonString.Contains("error") || jsonString.Contains("result")) { JsonResponseContext responseContext = jsonString.FromJson(); if (responseContext != null && !responseContext.id.IsNullOrEmpty()) { JsonRpcWaitResult waitContext = new JsonRpcWaitResult { Status = 1, Sign = long.Parse(responseContext.id), error = responseContext.error, Return = responseContext.result }; m_waitHandle.SetRun(waitContext); } } } catch { } return true; } #region RPC调用 /// /// /// /// /// public bool HasValue(IDependencyProperty dp) { return Client.HasValue(dp); } /// /// Rpc调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// /// public T Invoke(string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { JsonRpcWaitResult context = new JsonRpcWaitResult(); WaitData waitData = m_waitHandle.GetWaitData(context); using (ByteBlock byteBlock = BytePool.Default.GetByteBlock(BufferLength)) { if (invokeOption == default) { invokeOption = InvokeOption.WaitInvoke; } parameters ??= new object[0]; JsonRpcRequest jsonRpcRequest = new JsonRpcRequest() { method = method, @params = parameters }; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { jsonRpcRequest.id = context.Sign.ToString(); } else { jsonRpcRequest.id = null; } switch (m_jrpt) { case JRPT.Tcp: { byteBlock.Write(SerializeConvert.JsonSerializeToBytes(jsonRpcRequest)); break; } case JRPT.Http: { HttpRequest request = new HttpRequest(); request.Method = "POST"; request.SetUrl(RemoteIPHost.GetUrlPath()); request.FromJson(jsonRpcRequest.ToJson()); request.Build(byteBlock); break; } case JRPT.Websocket: { ((WebSocketClient)Client).SendWithWS(jsonRpcRequest.ToJson()); break; } } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return default; } case FeedbackType.WaitSend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return default; } case FeedbackType.WaitInvoke: { this.Send(byteBlock); waitData.Wait(invokeOption.Timeout); JsonRpcWaitResult resultContext = (JsonRpcWaitResult)waitData.WaitResult; m_waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new TimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RpcException(resultContext.error.message); } if (resultContext.Return == null) { return default; } if (typeof(T).IsPrimitive || typeof(T) == typeof(string)) { return (T)resultContext.Return.ToString().ParseToType(typeof(T)); } return resultContext.Return.ToJson().FromJson(); } default: return default; } } } /// /// Rpc调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// public void Invoke(string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { JsonRpcWaitResult context = new JsonRpcWaitResult(); WaitData waitData = m_waitHandle.GetWaitData(context); using (ByteBlock byteBlock = BytePool.Default.GetByteBlock(BufferLength)) { if (invokeOption == default) { invokeOption = InvokeOption.WaitInvoke; } parameters ??= new object[0]; JsonRpcRequest jsonRpcRequest = new JsonRpcRequest() { method = method, @params = parameters }; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { jsonRpcRequest.id = context.Sign.ToString(); } else { jsonRpcRequest.id = null; } switch (m_jrpt) { case JRPT.Tcp: { byteBlock.Write(SerializeConvert.JsonSerializeToBytes(jsonRpcRequest)); break; } case JRPT.Websocket: { ((WebSocketClient)Client).SendWithWS(jsonRpcRequest.ToJson()); break; } case JRPT.Http: { HttpRequest request = new HttpRequest(); request.Method = "POST"; request.SetUrl(RemoteIPHost.GetUrlPath()); request.FromJson(jsonRpcRequest.ToJson()); request.Build(byteBlock); } break; } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return; } case FeedbackType.WaitSend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return; } case FeedbackType.WaitInvoke: { this.Send(byteBlock); waitData.Wait(invokeOption.Timeout); JsonRpcWaitResult resultContext = (JsonRpcWaitResult)waitData.WaitResult; m_waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new TimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RpcException(resultContext.error.message); } break; } default: return; } } } /// /// Rpc调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// public void Invoke(string method, IInvokeOption invokeOption, params object[] parameters) { Invoke(method, invokeOption, ref parameters, null); } /// /// Rpc调用 /// /// 方法名 /// 调用配置 /// 参数 /// /// /// /// public T Invoke(string method, IInvokeOption invokeOption, params object[] parameters) { return Invoke(method, invokeOption, ref parameters, null); } /// /// 函数式调用 /// /// 函数名 /// 参数 /// Rpc调用设置 /// /// /// public async Task InvokeAsync(string method, IInvokeOption invokeOption, params object[] parameters) { JsonRpcWaitResult context = new JsonRpcWaitResult(); WaitData waitData = m_waitHandle.GetWaitData(context); using (ByteBlock byteBlock = BytePool.Default.GetByteBlock(BufferLength)) { if (invokeOption == default) { invokeOption = InvokeOption.WaitInvoke; } parameters ??= new object[0]; JsonRpcRequest jsonRpcRequest = new JsonRpcRequest() { method = method, @params = parameters }; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { jsonRpcRequest.id = context.Sign.ToString(); } else { jsonRpcRequest.id = null; } switch (m_jrpt) { case JRPT.Tcp: { byteBlock.Write(SerializeConvert.JsonSerializeToBytes(jsonRpcRequest)); break; } case JRPT.Websocket: { ((WebSocketClient)Client).SendWithWS(jsonRpcRequest.ToJson()); break; } case JRPT.Http: { HttpRequest request = new HttpRequest(); request.Method = "POST"; request.SetUrl(RemoteIPHost.GetUrlPath()); request.FromJson(jsonRpcRequest.ToJson()); request.Build(byteBlock); } break; } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return; } case FeedbackType.WaitSend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return; } case FeedbackType.WaitInvoke: { this.Send(byteBlock); await waitData.WaitAsync(invokeOption.Timeout); JsonRpcWaitResult resultContext = (JsonRpcWaitResult)waitData.WaitResult; m_waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new TimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RpcException(resultContext.error.message); } break; } default: return; } } } /// /// 函数式调用 /// /// 方法名 /// 参数 /// Rpc调用设置 /// 调用超时 /// Rpc异常 /// 其他异常 /// 服务器返回结果 public async Task InvokeAsync(string method, IInvokeOption invokeOption, params object[] parameters) { JsonRpcWaitResult context = new JsonRpcWaitResult(); WaitData waitData = m_waitHandle.GetWaitData(context); using (ByteBlock byteBlock = BytePool.Default.GetByteBlock(BufferLength)) { if (invokeOption == default) { invokeOption = InvokeOption.WaitInvoke; } parameters ??= new object[0]; JsonRpcRequest jsonRpcRequest = new JsonRpcRequest() { method = method, @params = parameters }; if (invokeOption.FeedbackType == FeedbackType.WaitInvoke) { jsonRpcRequest.id = context.Sign.ToString(); } else { jsonRpcRequest.id = null; } switch (m_jrpt) { case JRPT.Tcp: { byteBlock.Write(SerializeConvert.JsonSerializeToBytes(jsonRpcRequest)); break; } case JRPT.Http: { HttpRequest request = new HttpRequest(); request.Method = "POST"; request.SetUrl(RemoteIPHost.GetUrlPath()); request.FromJson(jsonRpcRequest.ToJson()); request.Build(byteBlock); break; } case JRPT.Websocket: { ((WebSocketClient)Client).SendWithWS(jsonRpcRequest.ToJson()); break; } } switch (invokeOption.FeedbackType) { case FeedbackType.OnlySend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return default; } case FeedbackType.WaitSend: { this.Send(byteBlock); m_waitHandle.Destroy(waitData); return default; } case FeedbackType.WaitInvoke: { this.Send(byteBlock); await waitData.WaitAsync(invokeOption.Timeout); JsonRpcWaitResult resultContext = (JsonRpcWaitResult)waitData.WaitResult; m_waitHandle.Destroy(waitData); if (resultContext.Status == 0) { throw new TimeoutException("等待结果超时"); } if (resultContext.error != null) { throw new RpcException(resultContext.error.message); } if (resultContext.Return == null) { return default; } if (typeof(T).IsPrimitive || typeof(T) == typeof(string)) { return (T)resultContext.Return.ToString().ParseToType(typeof(T)); } return resultContext.Return.ToJson().FromJson(); } default: return default; } } } /// /// /// /// /// /// public DependencyObject RemoveValue(IDependencyProperty dp) { return Client.RemoveValue(dp); } #endregion RPC调用 } }