Files
TouchSocket/RRQMSocket.RPC/RRQMRPC/Client/TcpRPCClient.cs
若汝棋茗 e1687b6023 优化Protocol
2021-06-11 01:25:33 +08:00

946 lines
35 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//------------------------------------------------------------------------------
// 此代码版权归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按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.Log;
using RRQMCore.Run;
using RRQMCore.Serialization;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// TcpRPCClient
/// </summary>
public class TcpRPCClient : TokenClient, IRPCClient
{
private RRQMAgreementHelper agreementHelper;
private MethodMap methodMap;
private MethodStore methodStore;
private RPCProxyInfo proxyFile;
private ServerProviderCollection serverProviders;
private WaitData<WaitResult> singleWaitData;
private RRQMWaitHandle<RPCContext> waitHandle;
/// <summary>
/// 构造函数
/// </summary>
public TcpRPCClient()
{
this.serverProviders = new ServerProviderCollection();
this.methodStore = new MethodStore();
this.singleWaitData = new WaitData<WaitResult>();
this.waitHandle = new RRQMWaitHandle<RPCContext>();
}
/// <summary>
/// 收到字节
/// </summary>
public event RRQMBytesEventHandler Received;
/// <summary>
/// 获取反向RPC映射图
/// </summary>
public MethodMap MethodMap
{
get { return methodMap; }
}
/// <summary>
/// 序列化生成器
/// </summary>
public SerializeConverter SerializeConverter { get; set; }
/// <summary>
/// 获取反向RPC服务实例
/// </summary>
public ServerProviderCollection ServerProviders
{
get { return serverProviders; }
}
/// <summary>
/// 连接
/// </summary>
public override void Connect()
{
lock (this)
{
base.Connect();
this.agreementHelper = new RRQMAgreementHelper(this);
try
{
this.methodStore = null;
agreementHelper.SocketSend(102);
}
catch (Exception e)
{
throw new RRQMRPCException(e.Message);
}
this.singleWaitData.Wait(1000 * 10);
if (this.methodStore == null)
{
throw new RRQMRPCException("初始化超时");
}
}
}
/// <summary>
/// 获取远程服务器RPC服务文件
/// </summary>
/// <exception cref="RRQMRPCException"></exception>
/// <exception cref="RRQMTimeoutException"></exception>
public RPCProxyInfo GetProxyInfo()
{
byte[] data = Encoding.UTF8.GetBytes((string)this.ClientConfig.GetValue(TcpRPCClientConfig.ProxyTokenProperty));
agreementHelper.SocketSend(100, data);
this.singleWaitData.Wait(1000 * 10);
if (this.proxyFile == null)
{
throw new RRQMTimeoutException("获取引用文件超时");
}
else if (this.proxyFile.Status == 2)
{
throw new RRQMRPCException(this.proxyFile.Message);
}
return this.proxyFile;
}
/// <summary>
/// 初始化RPC
/// </summary>
public void InitializedRPC()
{
if (!this.Online)
{
this.Connect();
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="method">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <param name="types"></param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
/// <returns></returns>
public T Invoke<T>(string method, InvokeOption invokeOption, ref object[] parameters, Type[] types)
{
if (!this.methodStore.TryGetMethodItem(method, out MethodItem methodItem))
{
throw new RRQMException($"服务名为{method}的服务未找到注册信息");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(101, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该公共方法或该方法未标记RRQMRPCMethod");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException("该方法已被禁用");
}
else if (resultContext.Status == 4)
{
throw new RRQMRPCException($"服务器已阻止本次行为,信息:{resultContext.Message}");
}
if (methodItem.IsOutOrRef)
{
try
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
}
else
{
parameters = null;
}
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
}
else
{
waitData.Dispose();
return default;
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="method">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <param name="types"></param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
public void Invoke(string method, InvokeOption invokeOption, ref object[] parameters, Type[] types)
{
if (!this.methodStore.TryGetMethodItem(method, out MethodItem methodItem))
{
throw new RRQMException($"服务名为{method}的服务未找到注册信息");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(101, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该公共方法或该方法未标记RRQMRPCMethod");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException("该方法已被禁用");
}
else if (resultContext.Status == 4)
{
throw new RRQMRPCException($"服务器已阻止本次行为,信息:{resultContext.Message}");
}
if (methodItem.IsOutOrRef)
{
try
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
}
else
{
parameters = null;
}
}
else
{
waitData.Dispose();
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="method">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
public void Invoke(string method, InvokeOption invokeOption, params object[] parameters)
{
if (!this.methodStore.TryGetMethodItem(method, out MethodItem methodItem))
{
throw new RRQMException($"服务名为{method}的服务未找到注册信息");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(101, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该公共方法或该方法未标记RRQMRPCMethod");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException("该方法已被禁用");
}
else if (resultContext.Status == 4)
{
throw new RRQMRPCException($"服务器已阻止本次行为,信息:{resultContext.Message}");
}
}
else
{
waitData.Dispose();
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="method">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
/// <returns></returns>
public T Invoke<T>(string method, InvokeOption invokeOption, params object[] parameters)
{
if (!this.methodStore.TryGetMethodItem(method, out MethodItem methodItem))
{
throw new RRQMException($"服务名为{method}的服务未找到注册信息");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(101, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该公共方法或该方法未标记RRQMRPCMethod");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException("该方法已被禁用");
}
else if (resultContext.Status == 4)
{
throw new RRQMRPCException($"服务器已阻止本次行为,信息:{resultContext.Message}");
}
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
}
else
{
waitData.Dispose();
return default;
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="id">客户端ID</param>
/// <param name="methodToken">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
public void Invoke(string id, int methodToken, InvokeOption invokeOption, params object[] parameters)
{
if (string.IsNullOrEmpty(id))
{
throw new RRQMRPCException("目标ID不能为null或empty");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.ID = id;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(103, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该客户端ID");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException(resultContext.Message);
}
}
else
{
waitData.Dispose();
}
}
/// <summary>
/// RPC调用
/// </summary>
/// <param name="id">客户端ID</param>
/// <param name="methodToken">方法名</param>
/// <param name="invokeOption">调用配置</param>
/// <param name="parameters">参数</param>
/// <exception cref="RRQMTimeoutException"></exception>
/// <exception cref="RRQMSerializationException"></exception>
/// <exception cref="RRQMRPCInvokeException"></exception>
/// <exception cref="RRQMException"></exception>
/// <returns></returns>
public T Invoke<T>(string id, int methodToken, InvokeOption invokeOption, params object[] parameters)
{
if (string.IsNullOrEmpty(id))
{
throw new RRQMRPCException("目标ID不能为null或empty");
}
RPCContext context = new RPCContext();
WaitData<RPCContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.ID = id;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
invokeOption = InvokeOption.CanFeedback;
}
try
{
if (invokeOption.Feedback)
{
context.Feedback = 1;
}
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
}
context.ParametersBytes = datas;
context.Serialize(byteBlock);
agreementHelper.SocketSend(103, byteBlock);
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
finally
{
byteBlock.Dispose();
}
if (invokeOption.Feedback)
{
waitData.Wait(invokeOption.WaitTime * 1000);
RPCContext resultContext = waitData.WaitResult;
waitData.Dispose();
if (resultContext.Status == 0)
{
throw new RRQMTimeoutException("等待结果超时");
}
else if (resultContext.Status == 2)
{
throw new RRQMRPCInvokeException("未找到该客户端ID");
}
else if (resultContext.Status == 3)
{
throw new RRQMRPCException(resultContext.Message);
}
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
throw new RRQMException(e.Message);
}
}
else
{
waitData.Dispose();
return default;
}
}
/// <summary>
/// 开启反向RPC服务
/// </summary>
public void OpenCallBackServer()
{
if (this.ServerProviders.Count == 0)
{
throw new RRQMRPCException("已注册服务数量为0");
}
this.methodMap = new MethodMap();
foreach (ServerProvider instance in this.ServerProviders)
{
MethodInfo[] methodInfos = instance.GetType().GetMethods();
foreach (MethodInfo method in methodInfos)
{
if (method.IsGenericMethod)
{
throw new RRQMRPCException("RPC方法中不支持泛型参数");
}
RRQMRPCCallBackMethodAttribute attribute = method.GetCustomAttribute<RRQMRPCCallBackMethodAttribute>();
if (attribute != null)
{
MethodInstance methodInstance = new MethodInstance();
methodInstance.MethodToken = attribute.MethodToken;
methodInstance.Provider = instance;
methodInstance.Method = method;
methodInstance.RPCAttributes = new RPCAttribute[] { attribute };
methodInstance.IsEnable = true;
methodInstance.Parameters = method.GetParameters();
List<string> names = new List<string>();
foreach (var parameterInfo in methodInstance.Parameters)
{
names.Add(parameterInfo.Name);
}
methodInstance.ParameterNames = names.ToArray();
if (typeof(Task).IsAssignableFrom(method.ReturnType))
{
methodInstance.Async = true;
}
ParameterInfo[] parameters = method.GetParameters();
List<Type> types = new List<Type>();
foreach (var parameter in parameters)
{
if (parameter.ParameterType.IsByRef)
{
throw new RRQMRPCException("反向RPC方法不支持out或ref");
}
types.Add(parameter.ParameterType);
}
methodInstance.ParameterTypes = types.ToArray();
if (method.ReturnType == typeof(void))
{
methodInstance.ReturnType = null;
}
else
{
if (methodInstance.Async)
{
methodInstance.ReturnType = method.ReturnType.GetGenericArguments()[0];
}
else
{
methodInstance.ReturnType = method.ReturnType;
}
}
try
{
this.MethodMap.Add(methodInstance);
}
catch
{
throw new RRQMRPCKeyException("MethodToken必须唯一");
}
}
}
}
}
/// <summary>
/// 注册服务
/// </summary>
/// <param name="serverProvider"></param>
public void RegistServer(ServerProvider serverProvider)
{
this.ServerProviders.Add(serverProvider);
}
/// <summary>
/// 发送
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public sealed override void Send(byte[] buffer, int offset, int length)
{
this.agreementHelper.SocketSend(120, buffer, offset, length);
}
/// <summary>
/// 发送
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
public sealed override void SendAsync(byte[] buffer, int offset, int length)
{
this.agreementHelper.SocketSend(120, buffer, offset, length);
}
/// <summary>
/// 收到信息
/// </summary>
/// <param name="byteBlock"></param>
/// <param name="obj"></param>
protected override void HandleReceivedData(ByteBlock byteBlock, object obj)
{
byte[] buffer = byteBlock.Buffer;
int r = (int)byteBlock.Length;
int agreement = BitConverter.ToInt32(buffer, 0);
switch (agreement)
{
case 100:/* 100表示获取RPC引用文件上传状态返回*/
{
try
{
proxyFile = SerializeConvert.RRQMBinaryDeserialize<RPCProxyInfo>(buffer, 4);
this.singleWaitData.Set();
}
catch
{
proxyFile = null;
}
break;
}
case 101:/*函数调用*/
{
try
{
RPCContext result = RPCContext.Deserialize(buffer, 4);
this.waitHandle.SetRun(result.Sign, result);
}
catch (Exception e)
{
Logger.Debug(LogType.Error, this, $"错误代码: 101, 错误详情:{e.Message}");
}
break;
}
case 102:/*获取服务*/
{
try
{
List<MethodItem> methodItems = SerializeConvert.RRQMBinaryDeserialize<List<MethodItem>>(buffer, 4);
this.methodStore = new MethodStore();
foreach (var item in methodItems)
{
this.methodStore.AddMethodItem(item);
}
this.singleWaitData.Set();
}
catch (Exception e)
{
Logger.Debug(LogType.Error, this, $"错误代码: 102, 错误详情:{e.Message}");
}
break;
}
case 103:/*ID函数调用*/
{
try
{
RPCContext result = RPCContext.Deserialize(buffer, 4);
this.waitHandle.SetRun(result.Sign, result);
}
catch (Exception e)
{
Logger.Debug(LogType.Error, this, $"错误代码: 103, 错误详情:{e.Message}");
}
break;
}
case 112:/*反向函数调用*/
{
Task.Run(() =>
{
RPCContext rpcContext = RPCContext.Deserialize(byteBlock.Buffer, 4);
ByteBlock block = this.BytePool.GetByteBlock(this.BufferLength);
try
{
rpcContext = this.OnExecuteCallBack(rpcContext);
rpcContext.Serialize(block);
agreementHelper.SocketSend(112, block);
}
catch (Exception e)
{
Logger.Debug(LogType.Error, this, $"错误代码: 112, 错误详情:{e.Message}");
}
finally
{
block.Dispose();
}
});
break;
}
case 120:/*接收数据*/
{
Task.Run(() =>
{
try
{
byte[] data = new byte[r - 4];
byteBlock.Position = 4;
byteBlock.Read(data);
this.Received?.Invoke(this, new BytesEventArgs(data));
}
catch (Exception e)
{
Logger.Debug(LogType.Error, this, $"错误代码: 120, 错误详情:{e.Message}");
}
});
break;
}
}
}
/// <summary>
/// 加载配置
/// </summary>
/// <param name="clientConfig"></param>
protected override void LoadConfig(TcpClientConfig clientConfig)
{
base.LoadConfig(clientConfig);
this.DataHandlingAdapter = new FixedHeaderDataHandlingAdapter();
this.SerializeConverter = (SerializeConverter)clientConfig.GetValue(TcpRPCClientConfig.SerializeConverterProperty);
}
private RPCContext OnExecuteCallBack(RPCContext rpcContext)
{
if (this.methodMap != null)
{
if (this.methodMap.TryGet(rpcContext.MethodToken, out MethodInstance methodInstance))
{
try
{
object[] ps = new object[rpcContext.ParametersBytes.Count];
for (int i = 0; i < rpcContext.ParametersBytes.Count; i++)
{
ps[i] = this.SerializeConverter.DeserializeParameter(rpcContext.ParametersBytes[i], methodInstance.ParameterTypes[i]);
}
object result = methodInstance.Method.Invoke(methodInstance.Provider, ps);
if (result != null)
{
rpcContext.ReturnParameterBytes = this.SerializeConverter.SerializeParameter(result);
}
rpcContext.Status = 1;
}
catch (Exception ex)
{
rpcContext.Status = 4;
rpcContext.Message = ex.Message;
}
}
else
{
rpcContext.Status = 2;
}
}
else
{
rpcContext.Status = 3;
}
rpcContext.ParametersBytes = null;
return rpcContext;
}
}
}