修改:序列化方式由客户端动态指定。

增加:支持调用上下文。
增加:支持客户端动态指定调用实例。
增加:Channel联合使用。
This commit is contained in:
若汝棋茗
2021-08-26 21:26:37 +08:00
parent 749b9c9fd2
commit e360b66726
37 changed files with 1451 additions and 904 deletions

View File

@@ -18,5 +18,32 @@ namespace RRQMSocket.RPC
/// </summary>
public abstract class RPCAttribute : Attribute
{
/// <summary>
/// 构造函数
/// </summary>
public RPCAttribute()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="methodFlags"></param>
public RPCAttribute(MethodFlags methodFlags)
{
this.methodFlags = methodFlags;
}
private MethodFlags methodFlags = MethodFlags.None;
/// <summary>
/// 函数标识
/// </summary>
public MethodFlags MethodFlags
{
get { return methodFlags; }
}
}
}

View File

@@ -0,0 +1,133 @@
using RRQMCore;
using RRQMCore.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// 工具
/// </summary>
internal static class GlobalTools
{
private static int nullReturnNullParameters = 100000000;
private static int nullReturnExistParameters = 300000000;
private static int ExistReturnNullParameters = 500000000;
private static int ExistReturnExistParameters = 700000000;
internal static MethodInstance[] GetMethodInstances(IServerProvider serverProvider, bool isSetToken)
{
List<MethodInstance> instances = new List<MethodInstance>();
MethodInfo[] methodInfos = serverProvider.GetType().GetMethods();
foreach (MethodInfo method in methodInfos)
{
if (method.IsGenericMethod)
{
continue;
}
IEnumerable<RPCAttribute> attributes = method.GetCustomAttributes<RPCAttribute>(true);
if (attributes.Count() > 0)
{
MethodInstance methodInstance = new MethodInstance();
methodInstance.Provider = serverProvider;
methodInstance.ProviderType = serverProvider.GetType();
methodInstance.Method = method;
methodInstance.RPCAttributes = attributes.ToArray();
methodInstance.IsEnable = true;
methodInstance.Parameters = method.GetParameters();
foreach (var item in attributes)
{
methodInstance.MethodFlags |= item.MethodFlags;
}
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
if (methodInstance.Parameters.Length==0||!typeof(IServerCallContext).IsAssignableFrom(methodInstance.Parameters[0].ParameterType) )
{
throw new RRQMRPCException($"函数:{method},标识包含{MethodFlags.IncludeCallContext}时,必须包含{nameof(IServerCallContext)}或其派生类参数,且为第一参数。");
}
}
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)
{
types.Add(parameter.ParameterType.GetRefOutType());
if (parameter.ParameterType.IsByRef)
{
methodInstance.IsByRef = true;
}
}
methodInstance.ParameterTypes = types.ToArray();
if (method.ReturnType == typeof(void) || method.ReturnType == typeof(Task))
{
methodInstance.ReturnType = null;
if (isSetToken)
{
if (parameters.Length == 0)
{
methodInstance.MethodToken = ++nullReturnNullParameters;
}
else
{
methodInstance.MethodToken = ++nullReturnExistParameters;
}
}
}
else
{
if (methodInstance.Async)
{
Type[] ts = method.ReturnType.GetGenericArguments();
if (ts.Length == 1)
{
methodInstance.ReturnType = ts[0];
}
else
{
methodInstance.ReturnType = null;
}
}
else
{
methodInstance.ReturnType = method.ReturnType;
}
if (isSetToken)
{
if (parameters.Length == 0)
{
methodInstance.MethodToken = ++ExistReturnNullParameters;
}
else
{
methodInstance.MethodToken = ++ExistReturnExistParameters;
}
}
}
instances.Add(methodInstance);
}
}
return instances.ToArray();
}
}
}

View File

@@ -10,6 +10,7 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Linq;
using System.Reflection;
namespace RRQMSocket.RPC
@@ -24,6 +25,11 @@ namespace RRQMSocket.RPC
/// </summary>
public IServerProvider Provider { get; internal set; }
/// <summary>
/// 实例类型
/// </summary>
public Type ProviderType { get; internal set; }
/// <summary>
/// RPC函数
/// </summary>
@@ -73,5 +79,25 @@ namespace RRQMSocket.RPC
/// 是否可用
/// </summary>
public bool IsEnable { get; internal set; }
/// <summary>
/// 函数标识
/// </summary>
public MethodFlags MethodFlags { get; internal set; }
/// <summary>
/// 获取指定类型属性标签
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T GetAttribute<T>()
{
object attribute = this.RPCAttributes.FirstOrDefault((a) => { return a.GetType() == typeof(T); });
if (attribute == null)
{
return default;
}
return (T)attribute;
}
}
}

View File

@@ -20,31 +20,41 @@ namespace RRQMSocket.RPC
/// <summary>
/// 返回值
/// </summary>
public object ReturnParameter { get; set; }
public object ReturnParameter;
/// <summary>
/// 参数值集合
/// </summary>
public object[] Parameters { get; set; }
public object[] Parameters;
/// <summary>
/// 获取调用状态
/// 调用状态
/// </summary>
public InvokeStatus Status { get; set; }
public InvokeStatus Status;
/// <summary>
/// 调用类型
/// </summary>
public InvokeType InvokeType;
/// <summary>
/// 自定义调用实例
/// </summary>
public IServerProvider CustomServerProvider;
/// <summary>
/// 状态消息
/// </summary>
public string StatusMessage { get; set; }
public string StatusMessage;
/// <summary>
/// 可以传递其他类型的数据容器
/// </summary>
public object Flag { get; set; }
public object Flag;
/// <summary>
/// 此函数执行者
/// </summary>
public object Caller { get; set; }
public ICaller Caller;
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// 调用类型
/// </summary>
public enum InvokeType : byte
{
/// <summary>
/// 全局实例
/// </summary>
GlobalInstance,
/// <summary>
/// 自定义实例
/// </summary>
CustomInstance,
/// <summary>
/// 每次调用都是新实例
/// </summary>
NewInstance
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// 函数标识
/// </summary>
[Flags]
public enum MethodFlags
{
/// <summary>
/// 空
/// </summary>
None=0,
/// <summary>
/// 包含调用者
/// </summary>
IncludeCallContext = 1
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// 调用RPC的实际调用者
/// </summary>
public interface ICaller
{
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// RPC上下文
/// </summary>
public interface IRpcContext
{
}
}

View File

@@ -0,0 +1,28 @@
namespace RRQMSocket.RPC
{
/// <summary>
/// 服务器调用上下文
/// </summary>
public interface IServerCallContext
{
/// <summary>
/// 函数实例
/// </summary>
MethodInstance MethodInstance { get; }
/// <summary>
/// 实际调用者
/// </summary>
ICaller Caller { get; }
/// <summary>
/// 调用信使
/// </summary>
MethodInvoker MethodInvoker { get; }
/// <summary>
/// RPC请求实际
/// </summary>
IRpcContext Context { get; }
}
}

View File

@@ -11,8 +11,8 @@
//------------------------------------------------------------------------------
using RRQMCore;
using RRQMCore.Exceptions;
using RRQMSocket.RPC.RRQMRPC;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -117,12 +117,11 @@ namespace RRQMSocket.RPC
public int RegisterAllServer()
{
Type[] types = (AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes()).Where(p => typeof(ServerProvider).IsAssignableFrom(p) && p.IsAbstract == false)).ToArray();
.SelectMany(s => s.GetTypes()).Where(p => typeof(ServerProvider).IsAssignableFrom(p) && !p.IsAbstract)).ToArray();
foreach (Type type in types)
{
ServerProvider serverProvider = Activator.CreateInstance(type) as ServerProvider;
RegisterServer(serverProvider);
this.RegisterServer(type);
}
return types.Length;
}
@@ -131,12 +130,10 @@ namespace RRQMSocket.RPC
/// 注册服务
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>返回T实例</returns>
/// <returns></returns>
public IServerProvider RegisterServer<T>() where T : IServerProvider
{
IServerProvider serverProvider = (IServerProvider)Activator.CreateInstance(typeof(T));
this.RegisterServer(serverProvider);
return serverProvider;
return this.RegisterServer(typeof(T));
}
/// <summary>
@@ -168,7 +165,7 @@ namespace RRQMSocket.RPC
{
throw new RRQMRPCException("请至少添加一种RPC解析器");
}
MethodInstance[] methodInstances = Tools.GetMethodInstances(serverProvider, true);
MethodInstance[] methodInstances = GlobalTools.GetMethodInstances(serverProvider, true);
foreach (var item in methodInstances)
{
@@ -266,16 +263,41 @@ namespace RRQMSocket.RPC
return this.UnregisterServer(typeof(T));
}
private readonly ConcurrentDictionary<string, ConcurrentDictionary<Type, IServerProvider>> idInvokeType = new ConcurrentDictionary<string, ConcurrentDictionary<Type, IServerProvider>>();
private IServerProvider GetServerProvider(MethodInvoker methodInvoker, MethodInstance methodInstance)
{
switch (methodInvoker.InvokeType)
{
default:
case InvokeType.GlobalInstance:
{
return methodInstance.Provider;
}
case InvokeType.CustomInstance:
{
if (methodInvoker.CustomServerProvider == null)
{
throw new RRQMRPCException($"调用类型为{InvokeType.CustomInstance}时,{methodInvoker.CustomServerProvider}不能为空。");
}
return methodInvoker.CustomServerProvider;
}
case InvokeType.NewInstance:
return (IServerProvider)Activator.CreateInstance(methodInstance.Provider.GetType());
}
}
private void ExecuteMethod(bool isAsync, IRPCParser parser, MethodInvoker methodInvoker, MethodInstance methodInstance)
{
IServerProvider serverProvider = this.GetServerProvider(methodInvoker, methodInstance);
if (methodInvoker.Status == InvokeStatus.Ready && methodInstance != null)
{
try
{
methodInstance.Provider.RPCEnter(parser, methodInvoker, methodInstance);
serverProvider.RPCEnter(parser, methodInvoker, methodInstance);
if (isAsync)
{
dynamic task = methodInstance.Method.Invoke(methodInstance.Provider, methodInvoker.Parameters);
dynamic task = methodInstance.Method.Invoke(serverProvider, methodInvoker.Parameters);
task.Wait();
if (methodInstance.ReturnType != null)
{
@@ -284,9 +306,9 @@ namespace RRQMSocket.RPC
}
else
{
methodInvoker.ReturnParameter = methodInstance.Method.Invoke(methodInstance.Provider, methodInvoker.Parameters);
methodInvoker.ReturnParameter = methodInstance.Method.Invoke(serverProvider, methodInvoker.Parameters);
}
methodInstance.Provider.RPCLeave(parser, methodInvoker, methodInstance);
serverProvider.RPCLeave(parser, methodInvoker, methodInstance);
methodInvoker.Status = InvokeStatus.Success;
}
catch (RRQMAbandonRPCException e)
@@ -305,13 +327,13 @@ namespace RRQMSocket.RPC
{
methodInvoker.StatusMessage = "函数内部发生异常,信息:未知";
}
methodInstance.Provider.RPCError(parser, methodInvoker, methodInstance);
serverProvider.RPCError(parser, methodInvoker, methodInstance);
}
catch (Exception e)
{
methodInvoker.Status = InvokeStatus.Exception;
methodInvoker.StatusMessage = e.Message;
methodInstance.Provider.RPCError(parser, methodInvoker, methodInstance);
serverProvider.RPCError(parser, methodInvoker, methodInstance);
}
}

View File

@@ -30,8 +30,27 @@ namespace RRQMSocket.RPC.RRQMRPC
/// 构造函数
/// </summary>
/// <param name="memberKey">指定键</param>
public RRQMRPCAttribute(string memberKey)
public RRQMRPCAttribute(string memberKey):this(memberKey,MethodFlags.None)
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="methodFlags"></param>
public RRQMRPCAttribute(MethodFlags methodFlags) : this(null, methodFlags)
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="memberKey"></param>
/// <param name="methodFlags"></param>
public RRQMRPCAttribute(string memberKey, MethodFlags methodFlags):base(methodFlags)
{
this.MemberKey = memberKey;
}
/// <summary>

View File

@@ -21,25 +21,27 @@ namespace RRQMSocket.RPC.RRQMRPC
/// </summary>
public class CodeGenerator
{
private StringBuilder codeString;
internal CodeGenerator()
{
codeString = new StringBuilder();
}
internal static string Namespace { get; set; }
internal static PropertyCodeGenerator PropertyCode { get; set; }
internal string ClassName { get; set; }
internal MethodInstance[] MethodInstances { get; set; }
internal static string GetAssemblyInfo(string assemblyName, string version)
{
CodeGenerator codeMap = new CodeGenerator();
codeMap.AppendAssemblyInfo(assemblyName, version);
return codeMap.codeString.ToString();
}
private StringBuilder codeString;
internal MethodInfo[] Methods { get; set; }
internal string ClassName { get; set; }
internal static string Namespace { get; set; }
internal static PropertyCodeGenerator PropertyCode { get; set; }
internal string GetCode()
{
codeString.AppendLine("using System;");
@@ -59,26 +61,9 @@ namespace RRQMSocket.RPC.RRQMRPC
return codeString.ToString();
}
private void GetInterface(string interfaceName)
internal string GetName(Type type)
{
codeString.AppendLine(string.Format("public interface {0}", interfaceName));//类开始
codeString.AppendLine("{");
codeString.AppendLine("IRpcClient Client{get;}");
AppendInterfaceMethods();
codeString.AppendLine("}");//类结束
}
private void GetClass(string className)
{
codeString.AppendLine(string.Format("public class {0} :I{0}", className));//类开始
codeString.AppendLine("{");
codeString.AppendLine($"public {className}(IRpcClient client)");
codeString.AppendLine("{");
codeString.AppendLine("this.Client=client;");
codeString.AppendLine("}");
AppendProperties();
AppendMethods();
codeString.AppendLine("}");//类结束
return PropertyCode.GetTypeFullName(type);
}
private void AppendAssemblyInfo(string assemblyName, string version)
@@ -95,25 +80,153 @@ namespace RRQMSocket.RPC.RRQMRPC
codeString.AppendLine(string.Format("[assembly: AssemblyFileVersion(\"{0}\")]", version.ToString()));
}
private void AppendProperties()
private void AppendInterfaceMethods()
{
codeString.AppendLine("public IRpcClient Client{get;private set; }");
if (MethodInstances != null)
{
foreach (MethodInstance methodInstance in MethodInstances)
{
bool isOut = false;
bool isRef = false;
MethodInfo method = methodInstance.Method;
string methodName = method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey == null ? method.Name : method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey;
if (method.ReturnType.FullName == "System.Void" || method.ReturnType.FullName == "System.Threading.Tasks.Task")
{
codeString.Append(string.Format(" void {0} ", methodName));
}
else
{
codeString.Append(string.Format(" {0} {1} ", this.GetName(method.ReturnType), methodName));
}
codeString.Append("(");//方法参数
ParameterInfo[] parameters ;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
List<ParameterInfo> infos = new List<ParameterInfo>(methodInstance.Parameters);
infos.RemoveAt(0);
parameters = infos.ToArray();
}
else
{
parameters = methodInstance.Parameters;
}
internal string GetName(Type type)
for (int i = 0; i < parameters.Length; i++)
{
return PropertyCode.GetTypeFullName(type);
if (i > 0)
{
codeString.Append(",");
}
if (parameters[i].ParameterType.Name.Contains("&"))
{
if (parameters[i].IsOut)
{
isOut = true;
codeString.Append(string.Format("out {0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
}
else
{
isRef = true;
codeString.Append(string.Format("ref {0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
}
}
else
{
codeString.Append(string.Format("{0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
}
if (parameters[i].HasDefaultValue)
{
object defaultValue = parameters[i].DefaultValue;
if (defaultValue == null)
{
codeString.Append(string.Format("=null"));
}
else if (defaultValue.ToString() == string.Empty)
{
codeString.Append(string.Format("=\"\""));
}
else if (defaultValue.GetType() == typeof(string))
{
codeString.Append(string.Format("=\"{0}\"", defaultValue));
}
else if (typeof(ValueType).IsAssignableFrom(defaultValue.GetType()))
{
codeString.Append(string.Format("={0}", defaultValue));
}
}
}
if (parameters.Length > 0)
{
codeString.Append(",");
}
codeString.AppendLine("InvokeOption invokeOption = null);");
if (!isOut && !isRef)//没有out或者ref
{
if (method.ReturnType.FullName == "System.Void" || method.ReturnType.FullName == "System.Threading.Tasks.Task")
{
codeString.Append(string.Format("void {0} ", methodName + "Async"));
}
else
{
codeString.Append(string.Format("Task<{0}> {1} ", this.GetName(method.ReturnType), methodName + "Async"));
}
codeString.Append("(");//方法参数
for (int i = 0; i < parameters.Length; i++)
{
if (i > 0)
{
codeString.Append(",");
}
codeString.Append(string.Format("{0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
if (parameters[i].DefaultValue != System.DBNull.Value)
{
object defaultValue = parameters[i].DefaultValue;
if (defaultValue == null)
{
codeString.Append(string.Format("=null"));
}
else if (defaultValue.ToString() == string.Empty)
{
codeString.Append(string.Format("=\"\""));
}
else if (defaultValue.GetType() == typeof(string))
{
codeString.Append(string.Format("=\"{0}\"", defaultValue));
}
else if (typeof(ValueType).IsAssignableFrom(defaultValue.GetType()))
{
codeString.Append(string.Format("={0}", defaultValue));
}
}
}
if (parameters.Length > 0)
{
codeString.Append(",");
}
codeString.AppendLine("InvokeOption invokeOption = null);");
}
}
}
}
private void AppendMethods()
{
if (Methods != null)
if (MethodInstances != null)
{
foreach (MethodInfo method in Methods)
foreach (MethodInstance methodInstance in MethodInstances)
{
bool isReturn;
bool isOut = false;
bool isRef = false;
MethodInfo method = methodInstance.Method;
string methodName = method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey == null ? method.Name : method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey;
if (method.ReturnType.FullName == "System.Void" || method.ReturnType.FullName == "System.Threading.Tasks.Task")
@@ -128,7 +241,17 @@ namespace RRQMSocket.RPC.RRQMRPC
}
codeString.Append("(");//方法参数
ParameterInfo[] parameters = method.GetParameters();
ParameterInfo[] parameters;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
List<ParameterInfo> infos = new List<ParameterInfo>(methodInstance.Parameters);
infos.RemoveAt(0);
parameters = infos.ToArray();
}
else
{
parameters = methodInstance.Parameters;
}
for (int i = 0; i < parameters.Length; i++)
{
@@ -373,130 +496,31 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
private void AppendInterfaceMethods()
private void AppendProperties()
{
if (Methods != null)
{
foreach (MethodInfo method in Methods)
{
bool isOut = false;
bool isRef = false;
string methodName = method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey == null ? method.Name : method.GetCustomAttribute<RRQMRPCAttribute>().MemberKey;
if (method.ReturnType.FullName == "System.Void" || method.ReturnType.FullName == "System.Threading.Tasks.Task")
{
codeString.Append(string.Format(" void {0} ", methodName));
}
else
{
codeString.Append(string.Format(" {0} {1} ", this.GetName(method.ReturnType), methodName));
}
codeString.Append("(");//方法参数
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
if (i > 0)
{
codeString.Append(",");
}
if (parameters[i].ParameterType.Name.Contains("&"))
{
if (parameters[i].IsOut)
{
isOut = true;
codeString.Append(string.Format("out {0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
}
else
{
isRef = true;
codeString.Append(string.Format("ref {0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
}
}
else
{
codeString.Append(string.Format("{0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
codeString.AppendLine("public IRpcClient Client{get;private set; }");
}
if (parameters[i].HasDefaultValue)
private void GetClass(string className)
{
object defaultValue = parameters[i].DefaultValue;
if (defaultValue == null)
{
codeString.Append(string.Format("=null"));
}
else if (defaultValue.ToString() == string.Empty)
{
codeString.Append(string.Format("=\"\""));
}
else if (defaultValue.GetType() == typeof(string))
{
codeString.Append(string.Format("=\"{0}\"", defaultValue));
}
else if (typeof(ValueType).IsAssignableFrom(defaultValue.GetType()))
{
codeString.Append(string.Format("={0}", defaultValue));
}
}
}
if (parameters.Length > 0)
{
codeString.Append(",");
}
codeString.AppendLine("InvokeOption invokeOption = null);");
if (!isOut && !isRef)//没有out或者ref
{
if (method.ReturnType.FullName == "System.Void" || method.ReturnType.FullName == "System.Threading.Tasks.Task")
{
codeString.Append(string.Format("void {0} ", methodName + "Async"));
}
else
{
codeString.Append(string.Format("Task<{0}> {1} ", this.GetName(method.ReturnType), methodName + "Async"));
codeString.AppendLine(string.Format("public class {0} :I{0}", className));//类开始
codeString.AppendLine("{");
codeString.AppendLine($"public {className}(IRpcClient client)");
codeString.AppendLine("{");
codeString.AppendLine("this.Client=client;");
codeString.AppendLine("}");
AppendProperties();
AppendMethods();
codeString.AppendLine("}");//类结束
}
codeString.Append("(");//方法参数
for (int i = 0; i < parameters.Length; i++)
private void GetInterface(string interfaceName)
{
if (i > 0)
{
codeString.Append(",");
}
codeString.Append(string.Format("{0} {1}", this.GetName(parameters[i].ParameterType), parameters[i].Name));
if (parameters[i].DefaultValue != System.DBNull.Value)
{
object defaultValue = parameters[i].DefaultValue;
if (defaultValue == null)
{
codeString.Append(string.Format("=null"));
}
else if (defaultValue.ToString() == string.Empty)
{
codeString.Append(string.Format("=\"\""));
}
else if (defaultValue.GetType() == typeof(string))
{
codeString.Append(string.Format("=\"{0}\"", defaultValue));
}
else if (typeof(ValueType).IsAssignableFrom(defaultValue.GetType()))
{
codeString.Append(string.Format("={0}", defaultValue));
}
}
}
if (parameters.Length > 0)
{
codeString.Append(",");
}
codeString.AppendLine("InvokeOption invokeOption = null);");
}
}
}
codeString.AppendLine(string.Format("public interface {0}", interfaceName));//类开始
codeString.AppendLine("{");
codeString.AppendLine("IRpcClient Client{get;}");
AppendInterfaceMethods();
codeString.AppendLine("}");//类结束
}
}
}

View File

@@ -10,6 +10,8 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.Serialization;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
@@ -57,6 +59,29 @@ namespace RRQMSocket.RPC.RRQMRPC
/// </summary>
public FeedbackType FeedbackType { get; set; }
private SerializationType serializationType = SerializationType.RRQMBinary;
/// <summary>
/// RRQMRPC序列化类型
/// </summary>
public SerializationType SerializationType
{
get { return serializationType; }
set { serializationType = value; }
}
private InvokeType invokeType= InvokeType.GlobalInstance;
/// <summary>
/// 调用类型
/// </summary>
public InvokeType InvokeType
{
get { return invokeType; }
set { invokeType = value; }
}
/// <summary>
/// 调用超时,
/// min=1000默认5000 ms

View File

@@ -0,0 +1,140 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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;
using RRQMCore.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
internal static class RRQMRPCTools
{
internal static void GetRPCMethod(
MethodInstance[] methodInstances,
string nameSpaceOld,
ref MethodStore methodStore,
Version version,
ref RpcProxyInfo proxyInfo)
{
string nameSpace = string.IsNullOrEmpty(nameSpaceOld) ? "RRQMRPC" : $"RRQMRPC.{nameSpaceOld}";
List<string> refs = new List<string>();
PropertyCodeGenerator propertyCode = new PropertyCodeGenerator(nameSpace, methodStore);
foreach (MethodInstance methodInstance in methodInstances)
{
foreach (RPCAttribute att in methodInstance.RPCAttributes)
{
if (att is RRQMRPCAttribute attribute)
{
if (methodInstance.ReturnType != null)
{
refs.Add(methodInstance.ReturnType.Assembly.Location);
propertyCode.AddTypeString(methodInstance.ReturnType);
}
int i = 0;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
i = 1;
}
for (; i < methodInstance.ParameterTypes.Length; i++)
{
refs.Add(methodInstance.ParameterTypes[i].Assembly.Location);
propertyCode.AddTypeString(methodInstance.ParameterTypes[i]);
}
break;
}
}
}
#if NET45_OR_GREATER
foreach (var item in refs)
{
RpcCompiler.AddRef(item);
}
#endif
string className = null;
List<MethodInstance> instances = new List<MethodInstance>();
foreach (MethodInstance methodInstance in methodInstances)
{
if (methodInstance.GetAttribute<RRQMRPCAttribute>() is RRQMRPCAttribute attribute)
{
MethodItem methodItem = new MethodItem();
methodItem.IsOutOrRef = methodInstance.IsByRef;
methodItem.MethodToken = methodInstance.MethodToken;
methodItem.ServerName = methodInstance.Provider.GetType().Name;
methodItem.Method = string.IsNullOrEmpty(attribute.MemberKey) ? methodInstance.Method.Name : attribute.MemberKey;
try
{
methodStore.AddMethodItem(methodItem);
}
catch
{
throw new RRQMRPCKeyException($"方法键为{methodItem.Method}的服务已注册");
}
if (className == null)
{
className = methodInstance.Provider.GetType().Name;
}
else if (className != methodInstance.Provider.GetType().Name)
{
throw new RRQMRPCException("方法来源于不同服务");
}
instances.Add(methodInstance);
}
}
CodeGenerator.Namespace = nameSpace;
CodeGenerator.PropertyCode = propertyCode;
CodeGenerator codeMap = new CodeGenerator();
codeMap.ClassName = className;
codeMap.MethodInstances = instances.ToArray();
CellCode cellCode = new CellCode();
cellCode.Name = className;
cellCode.CodeType = CodeType.Service;
cellCode.Code = codeMap.GetCode();
if (proxyInfo.Codes == null)
{
proxyInfo.Codes = new List<CellCode>();
}
proxyInfo.Codes.Add(cellCode);
CellCode argesCode = proxyInfo.Codes.FirstOrDefault(a => a.Name == "ClassArgs");
if (argesCode == null)
{
argesCode = new CellCode();
argesCode.Name = "ClassArgs";
argesCode.CodeType = CodeType.ClassArgs;
argesCode.Code = propertyCode.GetPropertyCode();
proxyInfo.Codes.Add(argesCode);
}
else
{
argesCode.Code = propertyCode.GetPropertyCode();
}
proxyInfo.AssemblyName = $"{nameSpace}.dll";
proxyInfo.Version = version == null ? "1.0.0.0" : version.ToString();
}
}
}

View File

@@ -11,6 +11,7 @@
//------------------------------------------------------------------------------
using RRQMCore.ByteManager;
using RRQMCore.Run;
using RRQMCore.Serialization;
using System.Collections.Generic;
namespace RRQMSocket.RPC.RRQMRPC
@@ -18,28 +19,110 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// RPC传输类
/// </summary>
public class RpcContext : WaitResult
public sealed class RpcContext : WaitResult, IRpcContext
{
internal int MethodToken;
internal string ID;
internal byte Feedback;
internal byte[] ReturnParameterBytes;
internal List<byte[]> ParametersBytes;
private byte feedback;
private byte serializationType;
private byte invokeType;
internal string id;
internal int methodToken;
internal List<byte[]> parametersBytes;
internal byte[] returnParameterBytes;
/// <summary>
/// 反馈类型
/// </summary>
public byte Feedback
{
get { return feedback; }
}
/// <summary>
/// 调用类型
/// </summary>
public InvokeType InvokeType
{
get { return (InvokeType)this.invokeType; }
}
/// <summary>
/// 序列化类型
/// </summary>
public SerializationType SerializationType
{
get { return (SerializationType)serializationType; }
}
/// <summary>
/// 调用ID
/// </summary>
public string ID
{
get { return id; }
}
/// <summary>
/// 函数键
/// </summary>
public int MethodToken
{
get { return methodToken; }
}
/// <summary>
/// 参数数据
/// </summary>
public byte[][] ParametersBytes
{
get { return parametersBytes.ToArray(); }
}
/// <summary>
/// 反回参数数据
/// </summary>
public byte[] ReturnParameterBytes
{
get { return returnParameterBytes; }
}
internal static RpcContext Deserialize(ByteBlock byteBlock)
{
RpcContext context = new RpcContext();
context.sign = byteBlock.ReadInt32();
context.status = byteBlock.ReadByte();
context.invokeType = byteBlock.ReadByte();
context.feedback = byteBlock.ReadByte();
context.serializationType = byteBlock.ReadByte();
context.methodToken = byteBlock.ReadInt32();
context.id = byteBlock.ReadString();
context.message = byteBlock.ReadString();
context.returnParameterBytes = byteBlock.ReadBytesPackage();
byte countPar = byteBlock.ReadByte();
context.parametersBytes = new List<byte[]>();
for (int i = 0; i < countPar; i++)
{
context.parametersBytes.Add(byteBlock.ReadBytesPackage());
}
return context;
}
internal void Serialize(ByteBlock byteBlock)
{
byteBlock.Write(this.Sign);
byteBlock.Write(this.Status);
byteBlock.Write(this.Feedback);
byteBlock.Write(this.MethodToken);
byteBlock.Write(this.ID);
byteBlock.Write(this.Message);
byteBlock.WriteBytesPackage(this.ReturnParameterBytes);
byteBlock.Write(this.sign);
byteBlock.Write(this.status);
byteBlock.Write(this.invokeType);
byteBlock.Write(this.feedback);
byteBlock.Write(this.serializationType);
byteBlock.Write(this.methodToken);
byteBlock.Write(this.id);
byteBlock.Write(this.message);
byteBlock.WriteBytesPackage(this.returnParameterBytes);
if (this.ParametersBytes != null && this.ParametersBytes.Count > 0)
if (this.parametersBytes != null && this.parametersBytes.Count > 0)
{
byteBlock.Write((byte)this.ParametersBytes.Count);
foreach (byte[] item in this.ParametersBytes)
byteBlock.Write((byte)this.parametersBytes.Count);
foreach (byte[] item in this.parametersBytes)
{
byteBlock.WriteBytesPackage(item);
}
@@ -50,25 +133,11 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
internal static RpcContext Deserialize(ByteBlock byteBlock)
internal void LoadInvokeOption(InvokeOption invokeOption)
{
RpcContext context = new RpcContext();
context.Sign = byteBlock.ReadInt32();
context.Status = byteBlock.ReadByte();
context.Feedback = byteBlock.ReadByte();
context.MethodToken = byteBlock.ReadInt32();
context.ID = byteBlock.ReadString();
context.Message = byteBlock.ReadString();
context.ReturnParameterBytes = byteBlock.ReadBytesPackage();
context.ParametersBytes = new List<byte[]>();
byte countPar = byteBlock.ReadByte();
for (int i = 0; i < countPar; i++)
{
context.ParametersBytes.Add(byteBlock.ReadBytesPackage());
}
return context;
this.invokeType = (byte)invokeOption.InvokeType;
this.feedback = (byte)invokeOption.FeedbackType;
this.serializationType = (byte)invokeOption.SerializationType;
}
}
}

View File

@@ -0,0 +1,30 @@
using RRQMCore.Serialization;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// RRQMRPC服务上下文
/// </summary>
public class RpcServerCallContext : IServerCallContext
{
internal ICaller caller;
internal RpcContext context;
internal MethodInstance methodInstance;
internal MethodInvoker methodInvoker;
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
public ICaller Caller => this.caller;
public IRpcContext Context => this.context;
public MethodInstance MethodInstance => this.methodInstance;
/// <summary>
/// 序列化类型
/// </summary>
public SerializationType SerializationType => this.context == null ? (SerializationType)byte.MaxValue : this.context.SerializationType;
public MethodInvoker MethodInvoker => methodInvoker;
}
}

View File

@@ -1,240 +0,0 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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;
using RRQMCore.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
internal static class Tools
{
internal static void GetRPCMethod(
MethodInstance[] methodInstances,
string nameSpaceOld,
ref MethodStore methodStore,
Version version,
ref RpcProxyInfo proxyInfo)
{
string nameSpace = string.IsNullOrEmpty(nameSpaceOld) ? "RRQMRPC" : $"RRQMRPC.{nameSpaceOld}";
List<string> refs = new List<string>();
PropertyCodeGenerator propertyCode = new PropertyCodeGenerator(nameSpace, methodStore);
foreach (MethodInstance methodInstance in methodInstances)
{
foreach (RPCAttribute att in methodInstance.RPCAttributes)
{
if (att is RRQMRPCAttribute attribute)
{
if (methodInstance.ReturnType != null)
{
refs.Add(methodInstance.ReturnType.Assembly.Location);
propertyCode.AddTypeString(methodInstance.ReturnType);
}
foreach (var type in methodInstance.ParameterTypes)
{
refs.Add(type.Assembly.Location);
propertyCode.AddTypeString(type);
}
break;
}
}
}
#if NET45_OR_GREATER
foreach (var item in refs)
{
RpcCompiler.AddRef(item);
}
#endif
List<MethodInfo> methods = new List<MethodInfo>();
string className = null;
foreach (MethodInstance methodInstance in methodInstances)
{
foreach (RPCAttribute att in methodInstance.RPCAttributes)
{
if (att is RRQMRPCAttribute attribute)
{
MethodItem methodItem = new MethodItem();
methodItem.IsOutOrRef = methodInstance.IsByRef;
methodItem.MethodToken = methodInstance.MethodToken;
methodItem.ServerName = methodInstance.Provider.GetType().Name;
methodItem.Method = string.IsNullOrEmpty(attribute.MemberKey) ? methodInstance.Method.Name : attribute.MemberKey;
try
{
methodStore.AddMethodItem(methodItem);
}
catch
{
throw new RRQMRPCKeyException($"方法键为{methodItem.Method}的服务已注册");
}
if (className == null)
{
className = methodInstance.Provider.GetType().Name;
}
else if (className != methodInstance.Provider.GetType().Name)
{
throw new RRQMRPCException("方法来源于不同服务");
}
methods.Add(methodInstance.Method);
break;
}
}
}
CodeGenerator.Namespace = nameSpace;
CodeGenerator.PropertyCode = propertyCode;
CodeGenerator codeMap = new CodeGenerator();
codeMap.ClassName = className;
codeMap.Methods = methods.ToArray();
CellCode cellCode = new CellCode();
cellCode.Name = className;
cellCode.CodeType = CodeType.Service;
cellCode.Code = codeMap.GetCode();
if (proxyInfo.Codes == null)
{
proxyInfo.Codes = new List<CellCode>();
}
proxyInfo.Codes.Add(cellCode);
CellCode argesCode = proxyInfo.Codes.FirstOrDefault(a => a.Name == "ClassArgs");
if (argesCode == null)
{
argesCode = new CellCode();
argesCode.Name = "ClassArgs";
argesCode.CodeType = CodeType.ClassArgs;
argesCode.Code = propertyCode.GetPropertyCode();
proxyInfo.Codes.Add(argesCode);
}
else
{
argesCode.Code = propertyCode.GetPropertyCode();
}
proxyInfo.AssemblyName = $"{nameSpace}.dll";
proxyInfo.Version = version == null ? "1.0.0.0" : version.ToString();
}
private static int nullReturnNullParameters = 1000000000;
private static int nullReturnExistParameters = 300000000;
private static int ExistReturnNullParameters = 500000000;
private static int ExistReturnExistParameters = 700000000;
internal static MethodInstance[] GetMethodInstances(IServerProvider serverProvider, bool isSetToken)
{
List<MethodInstance> instances = new List<MethodInstance>();
MethodInfo[] methodInfos = serverProvider.GetType().GetMethods();
foreach (MethodInfo method in methodInfos)
{
if (method.IsGenericMethod)
{
continue;
}
IEnumerable<RPCAttribute> attributes = method.GetCustomAttributes<RPCAttribute>(true);
if (attributes.Count() > 0)
{
MethodInstance methodInstance = new MethodInstance();
methodInstance.Provider = serverProvider;
methodInstance.Method = method;
methodInstance.RPCAttributes = attributes.ToArray();
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)
{
types.Add(parameter.ParameterType.GetRefOutType());
if (parameter.ParameterType.IsByRef)
{
methodInstance.IsByRef = true;
}
}
methodInstance.ParameterTypes = types.ToArray();
if (method.ReturnType == typeof(void) || method.ReturnType == typeof(Task))
{
methodInstance.ReturnType = null;
if (isSetToken)
{
if (parameters.Length == 0)
{
methodInstance.MethodToken = ++nullReturnNullParameters;
}
else
{
methodInstance.MethodToken = ++nullReturnExistParameters;
}
}
}
else
{
if (methodInstance.Async)
{
Type[] ts = method.ReturnType.GetGenericArguments();
if (ts.Length == 1)
{
methodInstance.ReturnType = ts[0];
}
else
{
methodInstance.ReturnType = null;
}
}
else
{
methodInstance.ReturnType = method.ReturnType;
}
if (isSetToken)
{
if (parameters.Length == 0)
{
methodInstance.MethodToken = ++ExistReturnNullParameters;
}
else
{
methodInstance.MethodToken = ++ExistReturnExistParameters;
}
}
}
instances.Add(methodInstance);
}
}
return instances.ToArray();
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC
{
/// <summary>
/// Udp调用者
/// </summary>
public class UdpCaller : ICaller
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="service"></param>
/// <param name="callerEndPoint"></param>
public UdpCaller(UdpSession service, EndPoint callerEndPoint)
{
this.service = service;
this.callerEndPoint = callerEndPoint;
}
private UdpSession service;
/// <summary>
/// Udp服务器
/// </summary>
public UdpSession Service
{
get { return service; }
}
private EndPoint callerEndPoint;
/// <summary>
/// 调用者终结点
/// </summary>
public EndPoint CallerEndPoint
{
get { return callerEndPoint; }
}
}
}

View File

@@ -36,16 +36,16 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// 序列化转换器
/// </summary>
public SerializeConverter SerializeConverter
public SerializationSelector SerializationSelector
{
get { return (SerializeConverter)GetValue(SerializeConverterProperty); }
set { SetValue(SerializeConverterProperty, value); }
get { return (SerializationSelector)GetValue(SerializationSelectorProperty); }
set { SetValue(SerializationSelectorProperty, value); }
}
/// <summary>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializeConverter"/>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializationSelector"/>
/// </summary>
public static readonly DependencyProperty SerializeConverterProperty =
DependencyProperty.Register("SerializeConverter", typeof(SerializeConverter), typeof(TcpRpcClientConfig), new BinarySerializeConverter());
public static readonly DependencyProperty SerializationSelectorProperty =
DependencyProperty.Register("SerializationSelector", typeof(SerializationSelector), typeof(TcpRpcClientConfig), new DefaultSerializationSelector());
}
}

View File

@@ -22,17 +22,17 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// 序列化转换器
/// </summary>
public SerializeConverter SerializeConverter
public SerializationSelector SerializationSelector
{
get { return (SerializeConverter)GetValue(SerializeConverterProperty); }
set { SetValue(SerializeConverterProperty, value); }
get { return (SerializationSelector)GetValue(SerializationSelectorProperty); }
set { SetValue(SerializationSelectorProperty, value); }
}
/// <summary>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializeConverter"/>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializationSelector"/>
/// </summary>
public static readonly DependencyProperty SerializeConverterProperty =
DependencyProperty.Register("SerializeConverter", typeof(SerializeConverter), typeof(TcpRpcParserConfig), new BinarySerializeConverter());
public static readonly DependencyProperty SerializationSelectorProperty =
DependencyProperty.Register("SerializationSelector", typeof(SerializationSelector), typeof(TcpRpcParserConfig), new DefaultSerializationSelector());
/// <summary>
/// 代理源文件命名空间

View File

@@ -36,16 +36,16 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// 序列化转换器
/// </summary>
public SerializeConverter SerializeConverter
public SerializationSelector SerializationSelector
{
get { return (SerializeConverter)GetValue(SerializeConverterProperty); }
set { SetValue(SerializeConverterProperty, value); }
get { return (SerializationSelector)GetValue(SerializationSelectorProperty); }
set { SetValue(SerializationSelectorProperty, value); }
}
/// <summary>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializeConverter"/>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializationSelector"/>
/// </summary>
public static readonly DependencyProperty SerializeConverterProperty =
DependencyProperty.Register("SerializeConverter", typeof(SerializeConverter), typeof(UdpRpcClientConfig), new BinarySerializeConverter());
public static readonly DependencyProperty SerializationSelectorProperty =
DependencyProperty.Register("SerializationSelector", typeof(SerializationSelector), typeof(UdpRpcClientConfig), new DefaultSerializationSelector());
}
}

View File

@@ -38,10 +38,10 @@ namespace RRQMSocket.RPC.RRQMRPC
DependencyProperty.Register("RPCVersion", typeof(Version), typeof(UdpRpcParserConfig), null);
/// <summary>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializeConverter"/>
/// 序列化转换器, 所需类型<see cref="RRQMRPC.SerializationSelector"/>
/// </summary>
public static readonly DependencyProperty SerializeConverterProperty =
DependencyProperty.Register("SerializeConverter", typeof(SerializeConverter), typeof(UdpRpcParserConfig), new BinarySerializeConverter());
public static readonly DependencyProperty SerializationSelectorProperty =
DependencyProperty.Register("SerializationSelector", typeof(SerializationSelector), typeof(UdpRpcParserConfig), new DefaultSerializationSelector());
/// <summary>
/// 代理源文件命名空间
@@ -73,10 +73,10 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// 序列化转换器
/// </summary>
public SerializeConverter SerializeConverter
public SerializationSelector SerializationSelector
{
get { return (SerializeConverter)GetValue(SerializeConverterProperty); }
set { SetValue(SerializeConverterProperty, value); }
get { return (SerializationSelector)GetValue(SerializationSelectorProperty); }
set { SetValue(SerializationSelectorProperty, value); }
}
}
}

View File

@@ -37,7 +37,7 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// 序列化生成器
/// </summary>
SerializeConverter SerializeConverter { get; }
SerializationSelector SerializationSelector { get; }
/// <summary>
/// 获取远程服务器RPC服务文件

View File

@@ -57,32 +57,32 @@ namespace RRQMSocket.RPC.RRQMRPC
Version RPCVersion { get; }
/// <summary>
/// 序列化转换
/// 序列化选择
/// </summary>
SerializeConverter SerializeConverter { get; }
SerializationSelector SerializationSelector { get; }
/// <summary>
/// 获取代理文件
/// </summary>
/// <param name="proxyToken">代理令箭</param>
/// <param name="caller">调用作用者TCP模式下派生自<see cref="RpcSocketClient"/>,UDP模式下是<see cref="EndPoint"/></param>
/// <param name="caller">调用作用者/></param>
/// <returns></returns>
RpcProxyInfo GetProxyInfo(string proxyToken, object caller);
RpcProxyInfo GetProxyInfo(string proxyToken, ICaller caller);
/// <summary>
/// 执行函数
/// </summary>
/// <param name="context">函数内容</param>
/// <param name="caller">调用作用者TCP模式下派生自<see cref="RpcSocketClient"/>,UDP模式下是<see cref="EndPoint"/></param>
void ExecuteContext(RpcContext context, object caller);
/// <param name="caller">调用作用者/></param>
void ExecuteContext(RpcContext context, ICaller caller);
/// <summary>
/// 获取注册函数
/// </summary>
/// <param name="proxyToken"></param>
/// <param name="caller">调用作用者TCP模式下派生自<see cref="RpcSocketClient"/>,UDP模式下是<see cref="EndPoint"/></param>
/// <param name="caller">调用作用者/></param>
/// <returns></returns>
List<MethodItem> GetRegisteredMethodItems(string proxyToken, object caller);
List<MethodItem> GetRegisteredMethodItems(string proxyToken, ICaller caller);
#if NET45_OR_GREATER

View File

@@ -1,44 +0,0 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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.Serialization;
using System;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// 二进制序列化器,默认最大可序列化1K byte的大小
/// </summary>
public class BinarySerializeConverter : SerializeConverter
{
#pragma warning disable CS1591 // XML 注释跟随抽象类
public override object DeserializeParameter(byte[] parameterBytes, Type parameterType)
{
if (parameterBytes == null)
{
return null;
}
return SerializeConvert.RRQMBinaryDeserialize(parameterBytes, 0, parameterType);
}
public override byte[] SerializeParameter(object parameter)
{
if (parameter == null)
{
return null;
}
return SerializeConvert.RRQMBinarySerialize(parameter, true);
}
#pragma warning restore CS1591
}
}

View File

@@ -0,0 +1,88 @@
using RRQMCore.Serialization;
using RRQMCore.XREF.Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// 默认序列化选择器
/// </summary>
public class DefaultSerializationSelector : SerializationSelector
{
/// <summary>
/// 反序列化
/// </summary>
/// <param name="serializationType"></param>
/// <param name="parameterBytes"></param>
/// <param name="parameterType"></param>
/// <returns></returns>
public override object DeserializeParameter(SerializationType serializationType, byte[] parameterBytes, Type parameterType)
{
if (parameterBytes == null)
{
return null;
}
switch (serializationType)
{
case SerializationType.RRQMBinary:
{
return SerializeConvert.RRQMBinaryDeserialize(parameterBytes, 0, parameterType);
}
case SerializationType.SystemBinary:
{
return SerializeConvert.BinaryDeserialize(parameterBytes, 0, parameterBytes.Length);
}
case SerializationType.Json:
{
return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(parameterBytes), parameterType);
}
case SerializationType.Xml:
{
return SerializeConvert.XmlDeserializeFromBytes(parameterBytes, parameterType);
}
default:
throw new RRQMRPCException("未指定的反序列化方式");
}
}
/// <summary>
/// 序列化参数
/// </summary>
/// <param name="serializationType"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public override byte[] SerializeParameter(SerializationType serializationType, object parameter)
{
if (parameter == null)
{
return null;
}
switch (serializationType)
{
case SerializationType.RRQMBinary:
{
return SerializeConvert.RRQMBinarySerialize(parameter, true);
}
case SerializationType.SystemBinary:
{
return SerializeConvert.BinarySerialize(parameter);
}
case SerializationType.Json:
{
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(parameter));
}
case SerializationType.Xml:
{
return SerializeConvert.XmlSerializeToBytes(parameter);
}
default:
throw new RRQMRPCException("未指定的序列化方式");
}
}
}
}

View File

@@ -1,55 +0,0 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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.XREF.Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// Json序列化转化器
/// </summary>
public class JsonSerializeConverter : RRQMSocket.RPC.RRQMRPC.SerializeConverter
{
/// <summary>
/// 反序列化
/// </summary>
/// <param name="parameterBytes"></param>
/// <param name="parameterType"></param>
/// <returns></returns>
public override object DeserializeParameter(byte[] parameterBytes, Type parameterType)
{
if (parameterBytes == null)
{
return null;
}
return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(parameterBytes), parameterType);
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public override byte[] SerializeParameter(object parameter)
{
if (parameter == null)
{
return null;
}
return Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(parameter));
}
}
}

View File

@@ -0,0 +1,32 @@
using RRQMCore.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// 序列化选择器
/// </summary>
public abstract class SerializationSelector
{
/// <summary>
/// 序列化RPC方法返回值参数
/// </summary>
/// <param name="serializationType"></param>
/// <param name="parameter"></param>
/// <returns></returns>
public abstract byte[] SerializeParameter(SerializationType serializationType, object parameter);
/// <summary>
/// 反序列化传输对象
/// </summary>
/// <param name="serializationType"></param>
/// <param name="parameterBytes"></param>
/// <param name="parameterType"></param>
/// <returns></returns>
public abstract object DeserializeParameter(SerializationType serializationType, byte[] parameterBytes, Type parameterType);
}
}

View File

@@ -1,36 +0,0 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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 System;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// 序列化转换器
/// </summary>
public abstract class SerializeConverter
{
/// <summary>
/// 序列化RPC方法返回值参数
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public abstract byte[] SerializeParameter(object parameter);
/// <summary>
/// 反序列化传输对象
/// </summary>
/// <param name="parameterBytes"></param>
/// <param name="parameterType"></param>
/// <returns></returns>
public abstract object DeserializeParameter(byte[] parameterBytes, Type parameterType);
}
}

View File

@@ -1,44 +0,0 @@
//------------------------------------------------------------------------------
// 此代码版权除特别声明或在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.Serialization;
using System;
namespace RRQMSocket.RPC.RRQMRPC
{
/// <summary>
/// Xml序列化
/// </summary>
public class XmlSerializeConverter : SerializeConverter
{
#pragma warning disable CS1591 // XML 注释
public override object DeserializeParameter(byte[] parameterBytes, Type parameterType)
{
if (parameterBytes == null)
{
return null;
}
return SerializeConvert.XmlDeserializeFromBytes(parameterBytes, parameterType);
}
public override byte[] SerializeParameter(object parameter)
{
if (parameter == null)
{
return null;
}
return SerializeConvert.XmlSerializeToBytes(parameter);
}
#pragma warning restore CS1591
}
}

View File

@@ -24,7 +24,7 @@ namespace RRQMSocket.RPC.RRQMRPC
/// <summary>
/// RPC服务器辅助类
/// </summary>
public class RpcSocketClient : ProtocolSocketClient
public class RpcSocketClient : ProtocolSocketClient, ICaller
{
static RpcSocketClient()
{
@@ -43,7 +43,7 @@ namespace RRQMSocket.RPC.RRQMRPC
internal RRQMReceivedProcotolEventHandler Received;
internal SerializeConverter serializeConverter;
internal SerializationSelector serializationSelector;
internal RRQMWaitHandle<RpcContext> waitHandle;
@@ -68,7 +68,7 @@ namespace RRQMSocket.RPC.RRQMRPC
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.methodToken = methodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
@@ -77,13 +77,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.serializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType,parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.InternalSend(104, byteBlock.Buffer, 0, byteBlock.Len);
@@ -141,7 +141,7 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
return (T)this.serializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
@@ -164,7 +164,7 @@ namespace RRQMSocket.RPC.RRQMRPC
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.methodToken = methodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
@@ -173,13 +173,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.serializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.InternalSend(104, byteBlock.Buffer, 0, byteBlock.Len);
@@ -250,15 +250,17 @@ namespace RRQMSocket.RPC.RRQMRPC
{
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = invokeContext.MethodToken;
context.methodToken = invokeContext.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
try
{
context.Feedback = invokeContext.Feedback;
context.ParametersBytes = invokeContext.ParametersBytes;
InvokeOption invokeOption = new InvokeOption();
invokeOption.FeedbackType = (FeedbackType)invokeContext.Feedback;
invokeOption.SerializationType = (SerializationType)invokeContext.Feedback;
context.LoadInvokeOption(invokeOption);
context.parametersBytes = invokeContext.parametersBytes;
context.Serialize(byteBlock);
this.InternalSend(104, byteBlock.Buffer, 0, byteBlock.Len);
@@ -365,19 +367,19 @@ namespace RRQMSocket.RPC.RRQMRPC
RpcContext content = RpcContext.Deserialize(byteBlock);
if (content.Feedback == 1)
{
List<byte[]> ps = content.ParametersBytes;
List<byte[]> ps = content.parametersBytes;
ByteBlock returnByteBlock = this.BytePool.GetByteBlock(this.BufferLength);
try
{
content.ParametersBytes = null;
content.parametersBytes = null;
content.Status = 1;
content.Serialize(returnByteBlock);
this.InternalSend(101, returnByteBlock.Buffer, 0, (int)returnByteBlock.Length);
}
finally
{
content.ParametersBytes = ps;
content.parametersBytes = ps;
returnByteBlock.Dispose();
}
}

View File

@@ -9,9 +9,11 @@
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore;
using RRQMCore.ByteManager;
using RRQMCore.Log;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
@@ -28,6 +30,7 @@ namespace RRQMSocket.RPC.RRQMRPC
/// </summary>
public TcpParser()
{
this.idTypeInstance = new ConcurrentDictionary<string, ConcurrentDictionary<Type, IServerProvider>>();
this.methodStore = new MethodStore();
this.proxyInfo = new RpcProxyInfo();
}
@@ -50,10 +53,15 @@ namespace RRQMSocket.RPC.RRQMRPC
public Version RPCVersion { get; private set; }
public SerializeConverter SerializeConverter { get; private set; }
private SerializationSelector serializationSelector;
public SerializationSelector SerializationSelector
{
get { return serializationSelector; }
}
private MethodStore methodStore;
private RpcProxyInfo proxyInfo;
public MethodStore MethodStore { get => methodStore; }
@@ -84,24 +92,30 @@ namespace RRQMSocket.RPC.RRQMRPC
{
if (methodInstance.MethodToken > 50000000)
{
context.ReturnParameterBytes = this.SerializeConverter.SerializeParameter(methodInvoker.ReturnParameter);
context.returnParameterBytes = this.serializationSelector.SerializeParameter(context.SerializationType, methodInvoker.ReturnParameter);
}
else
{
context.ReturnParameterBytes = null;
context.returnParameterBytes = null;
}
if (methodInstance.IsByRef)
{
context.ParametersBytes = new List<byte[]>();
foreach (var item in methodInvoker.Parameters)
context.parametersBytes = new List<byte[]>();
int i = 0;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
context.ParametersBytes.Add(this.SerializeConverter.SerializeParameter(item));
i = 1;
}
for (; i < methodInvoker.Parameters.Length; i++)
{
context.parametersBytes.Add(this.serializationSelector.SerializeParameter(context.SerializationType, methodInvoker.Parameters[i]));
}
}
else
{
context.ParametersBytes = null;
context.parametersBytes = null;
}
context.Status = 1;
@@ -149,7 +163,7 @@ namespace RRQMSocket.RPC.RRQMRPC
public void OnRegisterServer(IServerProvider provider, MethodInstance[] methodInstances)
{
Tools.GetRPCMethod(methodInstances, this.NameSpace, ref this.methodStore, this.RPCVersion, ref this.proxyInfo);
RRQMRPCTools.GetRPCMethod(methodInstances, this.NameSpace, ref this.methodStore, this.RPCVersion, ref this.proxyInfo);
}
public void OnUnregisterServer(IServerProvider provider, MethodInstance[] methodInstances)
@@ -210,13 +224,10 @@ namespace RRQMSocket.RPC.RRQMRPC
#endif
protected override void OnCreateSocketCliect(TClient socketClient, CreateOption createOption)
{
if (createOption.NewCreate)
{
socketClient.IDAction = this.IDInvoke;
socketClient.Received = this.OnReceived;
socketClient.serializeConverter = this.SerializeConverter;
}
socketClient.serializationSelector = this.serializationSelector;
}
private void OnReceived(object sender, short? procotol, ByteBlock byteBlock)
@@ -224,7 +235,7 @@ namespace RRQMSocket.RPC.RRQMRPC
this.Received?.Invoke(sender, procotol, byteBlock);
}
public virtual RpcProxyInfo GetProxyInfo(string proxyToken, object caller)
public virtual RpcProxyInfo GetProxyInfo(string proxyToken, ICaller caller)
{
RpcProxyInfo proxyInfo = new RpcProxyInfo();
if (this.ProxyToken == proxyToken)
@@ -244,23 +255,65 @@ namespace RRQMSocket.RPC.RRQMRPC
return proxyInfo;
}
public virtual void ExecuteContext(RpcContext context, object caller)
private readonly ConcurrentDictionary<string, ConcurrentDictionary<Type, IServerProvider>> idTypeInstance;
public virtual void ExecuteContext(RpcContext context, ICaller caller)
{
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.Caller = caller;
methodInvoker.Flag = context;
methodInvoker.InvokeType = context.InvokeType;
if (this.MethodMap.TryGet(context.MethodToken, out MethodInstance methodInstance))
{
try
{
if (methodInstance.IsEnable)
{
object[] ps = new object[methodInstance.ParameterTypes.Length];
object[] ps;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
ps = new object[methodInstance.ParameterTypes.Length];
RpcServerCallContext serverCallContext = new RpcServerCallContext();
serverCallContext.caller = caller;
serverCallContext.methodInvoker = methodInvoker;
serverCallContext.methodInstance = methodInstance;
serverCallContext.context = context;
ps[0] = serverCallContext;
for (int i = 0; i < context.parametersBytes.Count; i++)
{
ps[i + 1] = this.serializationSelector.DeserializeParameter(context.SerializationType, context.ParametersBytes[i], methodInstance.ParameterTypes[i + 1]);
}
}
else
{
ps = new object[methodInstance.ParameterTypes.Length];
for (int i = 0; i < methodInstance.ParameterTypes.Length; i++)
{
ps[i] = this.SerializeConverter.DeserializeParameter(context.ParametersBytes[i], methodInstance.ParameterTypes[i]);
ps[i] = this.serializationSelector.DeserializeParameter(context.SerializationType, context.ParametersBytes[i], methodInstance.ParameterTypes[i]);
}
}
methodInvoker.Parameters = ps;
if (context.InvokeType == InvokeType.CustomInstance)
{
ISocketClient socketClient = ((ISocketClient)caller);
ConcurrentDictionary<Type, IServerProvider> typeInstance;
if (!this.idTypeInstance.TryGetValue(socketClient.ID, out typeInstance))
{
typeInstance = new ConcurrentDictionary<Type, IServerProvider>();
this.idTypeInstance.TryAdd(socketClient.ID, typeInstance);
}
IServerProvider instance;
if (!typeInstance.TryGetValue(methodInstance.ProviderType, out instance))
{
instance = (IServerProvider)Activator.CreateInstance(methodInstance.ProviderType);
typeInstance.TryAdd(methodInstance.ProviderType, instance);
}
methodInvoker.CustomServerProvider = instance;
}
}
else
{
@@ -285,13 +338,13 @@ namespace RRQMSocket.RPC.RRQMRPC
protected override void LoadConfig(ServiceConfig ServiceConfig)
{
base.LoadConfig(ServiceConfig);
this.SerializeConverter = (SerializeConverter)ServiceConfig.GetValue(TcpRpcParserConfig.SerializeConverterProperty);
this.serializationSelector = (SerializationSelector)ServiceConfig.GetValue(TcpRpcParserConfig.SerializationSelectorProperty);
this.ProxyToken = (string)ServiceConfig.GetValue(TcpRpcParserConfig.ProxyTokenProperty);
this.NameSpace = (string)ServiceConfig.GetValue(TcpRpcParserConfig.NameSpaceProperty);
this.RPCVersion = (Version)ServiceConfig.GetValue(TcpRpcParserConfig.RPCVersionProperty);
}
public virtual List<MethodItem> GetRegisteredMethodItems(string proxyToken, object caller)
public virtual List<MethodItem> GetRegisteredMethodItems(string proxyToken, ICaller caller)
{
if (proxyToken == this.ProxyToken)
{
@@ -306,7 +359,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
try
{
context.ReturnParameterBytes = targetsocketClient.CallBack(context, 5);
context.returnParameterBytes = targetsocketClient.CallBack(context, 5);
context.Status = 1;
}
catch (Exception ex)
@@ -369,6 +422,5 @@ namespace RRQMSocket.RPC.RRQMRPC
throw new RRQMRPCException("未找到该客户端");
}
}
}
}

View File

@@ -84,10 +84,15 @@ namespace RRQMSocket.RPC.RRQMRPC
get { return methodMap; }
}
private SerializationSelector serializationSelector;
/// <summary>
/// 序列化生成
/// 序列化选择
/// </summary>
public SerializeConverter SerializeConverter { get; private set; }
public SerializationSelector SerializationSelector
{
get { return serializationSelector; }
}
/// <summary>
/// 获取反向RPC服务实例
@@ -136,7 +141,7 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
this.methodStore = null;
string proxyToken = (string)this.clientConfig.GetValue(TcpRpcClientConfig.ProxyTokenProperty);
string proxyToken = (string)this.ClientConfig.GetValue(TcpRpcClientConfig.ProxyTokenProperty);
byte[] data = new byte[0];
if (!string.IsNullOrEmpty(proxyToken))
{
@@ -183,7 +188,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -191,14 +196,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
switch (invokeOption.FeedbackType)
@@ -286,7 +290,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
parameters[i] = this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
@@ -300,7 +304,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception ex)
{
@@ -332,7 +336,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -340,13 +344,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
switch (invokeOption.FeedbackType)
{
@@ -428,7 +432,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
parameters[i] = this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception ex)
@@ -464,7 +468,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -472,13 +476,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
switch (invokeOption.FeedbackType)
{
@@ -581,7 +585,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -589,13 +593,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
switch (invokeOption.FeedbackType)
{
@@ -677,7 +681,7 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception ex)
{
@@ -708,8 +712,8 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.ID = id;
context.methodToken = methodToken;
context.id = id;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -717,13 +721,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.InternalSend(103, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -791,8 +795,8 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<WaitResult> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodToken;
context.ID = id;
context.methodToken = methodToken;
context.id = id;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -800,13 +804,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.InternalSend(103, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -848,7 +852,7 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception ex)
{
@@ -1119,7 +1123,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
base.LoadConfig(clientConfig);
this.SetDataHandlingAdapter(new FixedHeaderDataHandlingAdapter());
this.SerializeConverter = (SerializeConverter)clientConfig.GetValue(TcpRpcClientConfig.SerializeConverterProperty);
this.serializationSelector = (SerializationSelector)clientConfig.GetValue(TcpRpcClientConfig.SerializationSelectorProperty);
}
/// <summary>
@@ -1166,15 +1170,15 @@ namespace RRQMSocket.RPC.RRQMRPC
{
try
{
object[] ps = new object[rpcContext.ParametersBytes.Count];
for (int i = 0; i < rpcContext.ParametersBytes.Count; i++)
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]);
ps[i] = this.serializationSelector.DeserializeParameter(rpcContext.SerializationType,rpcContext.ParametersBytes[i], methodInstance.ParameterTypes[i]);
}
object result = methodInstance.Method.Invoke(methodInstance.Provider, ps);
if (result != null)
{
rpcContext.ReturnParameterBytes = this.SerializeConverter.SerializeParameter(result);
rpcContext.returnParameterBytes = this.serializationSelector.SerializeParameter(rpcContext.SerializationType,result);
}
rpcContext.Status = 1;
}
@@ -1194,7 +1198,7 @@ namespace RRQMSocket.RPC.RRQMRPC
rpcContext.Status = 3;
}
rpcContext.ParametersBytes = null;
rpcContext.parametersBytes = null;
return rpcContext;
}
}

View File

@@ -43,7 +43,6 @@ namespace RRQMSocket.RPC.RRQMRPC
public UdpRpcClient()
{
this.waitHandle = new RRQMWaitHandle<RpcContext>();
this.SerializeConverter = new BinarySerializeConverter();
this.waitResult = new WaitResult();
this.singleWaitData = new WaitData<WaitResult>();
}
@@ -53,10 +52,15 @@ namespace RRQMSocket.RPC.RRQMRPC
/// </summary>
public string ID => null;
private SerializationSelector serializationSelector;
/// <summary>
/// 序列化生成
/// 序列化选择
/// </summary>
public SerializeConverter SerializeConverter { get; set; }
public SerializationSelector SerializationSelector
{
get { return serializationSelector; }
}
/// <summary>
/// 获取远程服务器RPC服务文件
@@ -163,7 +167,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -171,14 +175,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.UDPSend(101, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -249,7 +252,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
parameters[i] = this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
@@ -263,7 +266,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
@@ -294,7 +297,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -302,13 +305,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.UDPSend(101, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -375,7 +378,7 @@ namespace RRQMSocket.RPC.RRQMRPC
{
for (int i = 0; i < parameters.Length; i++)
{
parameters[i] = this.SerializeConverter.DeserializeParameter(resultContext.ParametersBytes[i], types[i]);
parameters[i] = this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ParametersBytes[i], types[i]);
}
}
catch (Exception e)
@@ -410,7 +413,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -418,13 +421,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.UDPSend(101, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -511,7 +514,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
RpcContext context = new RpcContext();
WaitData<RpcContext> waitData = this.waitHandle.GetWaitData(context);
context.MethodToken = methodItem.MethodToken;
context.methodToken = methodItem.MethodToken;
ByteBlock byteBlock = this.BytePool.GetByteBlock(this.BufferLength);
if (invokeOption == null)
{
@@ -519,13 +522,13 @@ namespace RRQMSocket.RPC.RRQMRPC
}
try
{
context.Feedback = (byte)invokeOption.FeedbackType;
context.LoadInvokeOption(invokeOption);
List<byte[]> datas = new List<byte[]>();
foreach (object parameter in parameters)
{
datas.Add(this.SerializeConverter.SerializeParameter(parameter));
datas.Add(this.serializationSelector.SerializeParameter(context.SerializationType, parameter));
}
context.ParametersBytes = datas;
context.parametersBytes = datas;
context.Serialize(byteBlock);
this.UDPSend(101, byteBlock.Buffer, 0, byteBlock.Len);
}
@@ -592,7 +595,7 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
return (T)this.SerializeConverter.DeserializeParameter(resultContext.ReturnParameterBytes, typeof(T));
return (T)this.serializationSelector.DeserializeParameter(resultContext.SerializationType, resultContext.ReturnParameterBytes, typeof(T));
}
catch (Exception e)
{
@@ -604,6 +607,15 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
/// <summary>
/// 加载配置
/// </summary>
/// <param name="serverConfig"></param>
protected override void LoadConfig(ServiceConfig serverConfig)
{
base.LoadConfig(serverConfig);
this.serializationSelector = (SerializationSelector)serverConfig.GetValue(UdpRpcClientConfig.SerializationSelectorProperty);
}
/// <summary>
/// 密封数据

View File

@@ -25,6 +25,12 @@ namespace RRQMSocket.RPC.RRQMRPC
/// </summary>
public class UdpRpcParser : UdpSession, IRPCParser, IRRQMRpcParser
{
private MethodStore methodStore;
private RpcProxyInfo proxyInfo;
private SerializationSelector serializationSelector;
/// <summary>
/// 构造函数
/// </summary>
@@ -34,67 +40,84 @@ namespace RRQMSocket.RPC.RRQMRPC
this.proxyInfo = new RpcProxyInfo();
}
#pragma warning disable
public MethodMap MethodMap { get; private set; }
public RPCService RPCService { get; private set; }
public Action<IRPCParser, MethodInvoker, MethodInstance> RRQMExecuteMethod { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public CellCode[] Codes { get => this.proxyInfo == null ? null : this.proxyInfo.Codes.ToArray(); }
public string NameSpace { get; private set; }
public RpcProxyInfo ProxyInfo { get => proxyInfo; }
public string ProxyToken { get; private set; }
public Version RPCVersion { get; private set; }
public SerializeConverter SerializeConverter { get; private set; }
private MethodStore methodStore;
private RpcProxyInfo proxyInfo;
/// <summary>
/// <inheritdoc/>
/// </summary>
public MethodMap MethodMap { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public MethodStore MethodStore => this.methodStore;
public void SetExecuteMethod(Action<IRPCParser, MethodInvoker, MethodInstance> executeMethod)
/// <summary>
/// <inheritdoc/>
/// </summary>
public string NameSpace { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public RpcProxyInfo ProxyInfo { get => proxyInfo; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public string ProxyToken { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public RPCService RPCService { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public Version RPCVersion { get; private set; }
/// <summary>
/// <inheritdoc/>
/// </summary>
public Action<IRPCParser, MethodInvoker, MethodInstance> RRQMExecuteMethod { get; private set; }
/// <summary>
/// 序列化选择器
/// </summary>
public SerializationSelector SerializationSelector
{
this.RRQMExecuteMethod = executeMethod;
get { return serializationSelector; }
}
public void SetMethodMap(MethodMap methodMap)
#if NET45_OR_GREATER
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="targetDic"><inheritdoc/></param>
public void CompilerProxy(string targetDic = "")
{
this.MethodMap = methodMap;
string assemblyInfo = CodeGenerator.GetAssemblyInfo(this.proxyInfo.AssemblyName, this.proxyInfo.Version);
List<string> codesString = new List<string>();
codesString.Add(assemblyInfo);
foreach (var item in this.proxyInfo.Codes)
{
codesString.Add(item.Code);
}
RpcCompiler.CompileCode(Path.Combine(targetDic, this.proxyInfo.AssemblyName), codesString.ToArray());
}
public void SetRPCService(RPCService service)
{
this.RPCService = service;
}
#endif
public virtual RpcProxyInfo GetProxyInfo(string proxyToken, object caller)
{
RpcProxyInfo proxyInfo = new RpcProxyInfo();
if (this.ProxyToken == proxyToken)
{
proxyInfo.AssemblyData = this.ProxyInfo.AssemblyData;
proxyInfo.AssemblyName = this.ProxyInfo.AssemblyName;
proxyInfo.Codes = this.ProxyInfo.Codes;
proxyInfo.Version = this.ProxyInfo.Version;
proxyInfo.Status = 1;
}
else
{
proxyInfo.Status = 2;
proxyInfo.Message = "令箭不正确";
}
return proxyInfo;
}
public virtual void ExecuteContext(RpcContext context, object caller)
/// <summary>
/// <inheritdoc/>
/// </summary>
public virtual void ExecuteContext(RpcContext context, ICaller caller)
{
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.Caller = caller;
@@ -105,10 +128,28 @@ namespace RRQMSocket.RPC.RRQMRPC
{
if (methodInstance.IsEnable)
{
object[] ps = new object[methodInstance.ParameterTypes.Length];
object[] ps;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
ps = new object[methodInstance.ParameterTypes.Length];
RpcServerCallContext serverCallContext = new RpcServerCallContext();
serverCallContext.caller = caller;
serverCallContext.methodInstance = methodInstance;
serverCallContext.methodInvoker = methodInvoker;
serverCallContext.context = context;
ps[0] = serverCallContext;
for (int i = 0; i < context.parametersBytes.Count; i++)
{
ps[i + 1] = this.serializationSelector.DeserializeParameter(context.SerializationType, context.ParametersBytes[i], methodInstance.ParameterTypes[i + 1]);
}
}
else
{
ps = new object[methodInstance.ParameterTypes.Length];
for (int i = 0; i < methodInstance.ParameterTypes.Length; i++)
{
ps[i] = this.SerializeConverter.DeserializeParameter(context.ParametersBytes[i], methodInstance.ParameterTypes[i]);
ps[i] = this.serializationSelector.DeserializeParameter(context.SerializationType, context.ParametersBytes[i], methodInstance.ParameterTypes[i]);
}
}
methodInvoker.Parameters = ps;
}
@@ -132,47 +173,40 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
protected override void LoadConfig(ServiceConfig ServiceConfig)
/// <summary>
/// <inheritdoc/>
/// </summary>
public virtual RpcProxyInfo GetProxyInfo(string proxyToken, ICaller caller)
{
base.LoadConfig(ServiceConfig);
this.SerializeConverter = (SerializeConverter)ServiceConfig.GetValue(UdpRpcParserConfig.SerializeConverterProperty);
this.ProxyToken = (string)ServiceConfig.GetValue(UdpRpcParserConfig.ProxyTokenProperty);
this.NameSpace = (string)ServiceConfig.GetValue(UdpRpcParserConfig.NameSpaceProperty);
this.RPCVersion = (Version)ServiceConfig.GetValue(UdpRpcParserConfig.RPCVersionProperty);
RpcProxyInfo proxyInfo = new RpcProxyInfo();
if (this.ProxyToken == proxyToken)
{
proxyInfo.AssemblyData = this.ProxyInfo.AssemblyData;
proxyInfo.AssemblyName = this.ProxyInfo.AssemblyName;
proxyInfo.Codes = this.ProxyInfo.Codes;
proxyInfo.Version = this.ProxyInfo.Version;
proxyInfo.Status = 1;
}
else
{
proxyInfo.Status = 2;
proxyInfo.Message = "令箭不正确";
}
public virtual List<MethodItem> GetRegisteredMethodItems(string proxyToken, object caller)
return proxyInfo;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public virtual List<MethodItem> GetRegisteredMethodItems(string proxyToken, ICaller caller)
{
return this.methodStore.GetAllMethodItem();
}
public void OnRegisterServer(IServerProvider provider, MethodInstance[] methodInstances)
{
Tools.GetRPCMethod(methodInstances, this.NameSpace, ref this.methodStore, this.RPCVersion, ref this.proxyInfo);
}
public void OnUnregisterServer(IServerProvider provider, MethodInstance[] methodInstances)
{
foreach (var item in methodInstances)
{
this.methodStore.RemoveMethodItem(item.MethodToken);
}
CellCode cellCode = null;
foreach (var item in this.proxyInfo.Codes)
{
if (item.Name == provider.GetType().Name)
{
cellCode = item;
break;
}
}
if (cellCode != null)
{
this.proxyInfo.Codes.Remove(cellCode);
}
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public void OnEndInvoke(MethodInvoker methodInvoker, MethodInstance methodInstance)
{
RpcContext context = (RpcContext)methodInvoker.Flag;
@@ -199,24 +233,29 @@ namespace RRQMSocket.RPC.RRQMRPC
{
if (methodInstance.MethodToken > 50000000)
{
context.ReturnParameterBytes = this.SerializeConverter.SerializeParameter(methodInvoker.ReturnParameter);
context.returnParameterBytes = this.serializationSelector.SerializeParameter(context.SerializationType, methodInvoker.ReturnParameter);
}
else
{
context.ReturnParameterBytes = null;
context.returnParameterBytes = null;
}
if (methodInstance.IsByRef)
{
context.ParametersBytes = new List<byte[]>();
foreach (var item in methodInvoker.Parameters)
context.parametersBytes = new List<byte[]>();
int i = 0;
if (methodInstance.MethodFlags.HasFlag(MethodFlags.IncludeCallContext))
{
context.ParametersBytes.Add(this.SerializeConverter.SerializeParameter(item));
i = 1;
}
for (; i < methodInvoker.Parameters.Length; i++)
{
context.parametersBytes.Add(this.serializationSelector.SerializeParameter(context.SerializationType, methodInvoker.Parameters[i]));
}
}
else
{
context.ParametersBytes = null;
context.parametersBytes = null;
}
context.Status = 1;
@@ -250,7 +289,7 @@ namespace RRQMSocket.RPC.RRQMRPC
}
context.Serialize(byteBlock);
this.UDPSend(101, (EndPoint)methodInvoker.Caller, byteBlock.Buffer, 0, byteBlock.Len);
this.UDPSend(101, ((UdpCaller)methodInvoker.Caller).CallerEndPoint, byteBlock.Buffer, 0, byteBlock.Len);
}
catch (Exception ex)
{
@@ -262,26 +301,61 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
#pragma warning restore
private void UDPSend(short procotol, EndPoint endPoint, byte[] buffer, int offset, int length)
/// <summary>
/// <inheritdoc/>
/// </summary>
public void OnRegisterServer(IServerProvider provider, MethodInstance[] methodInstances)
{
ByteBlock byteBlock = this.BytePool.GetByteBlock(length + 2);
try
{
byteBlock.Write(BitConverter.GetBytes(procotol));
byteBlock.Write(buffer, offset, length);
this.SendTo(byteBlock.Buffer, 0, byteBlock.Len, endPoint);
RRQMRPCTools.GetRPCMethod(methodInstances, this.NameSpace, ref this.methodStore, this.RPCVersion, ref this.proxyInfo);
}
finally
/// <summary>
/// <inheritdoc/>
/// </summary>
public void OnUnregisterServer(IServerProvider provider, MethodInstance[] methodInstances)
{
byteBlock.Dispose();
foreach (var item in methodInstances)
{
this.methodStore.RemoveMethodItem(item.MethodToken);
}
CellCode cellCode = null;
foreach (var item in this.proxyInfo.Codes)
{
if (item.Name == provider.GetType().Name)
{
cellCode = item;
break;
}
}
if (cellCode != null)
{
this.proxyInfo.Codes.Remove(cellCode);
}
}
private void UDPSend(short procotol, EndPoint endPoint, byte[] buffer)
/// <summary>
/// <inheritdoc/>
/// </summary>
public void SetExecuteMethod(Action<IRPCParser, MethodInvoker, MethodInstance> executeMethod)
{
this.UDPSend(procotol, endPoint, buffer, 0, buffer.Length);
this.RRQMExecuteMethod = executeMethod;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public void SetMethodMap(MethodMap methodMap)
{
this.MethodMap = methodMap;
}
/// <summary>
/// <inheritdoc/>
/// </summary>
public void SetRPCService(RPCService service)
{
this.RPCService = service;
}
/// <summary>
@@ -302,7 +376,8 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
string proxyToken = Encoding.UTF8.GetString(buffer, 2, r - 2);
this.UDPSend(100, remoteEndPoint, SerializeConvert.RRQMBinarySerialize(this.GetProxyInfo(proxyToken, remoteEndPoint), true));
this.UDPSend(100, remoteEndPoint,
SerializeConvert.RRQMBinarySerialize(this.GetProxyInfo(proxyToken, new UdpCaller(this, remoteEndPoint)), true));
}
catch (Exception e)
{
@@ -319,23 +394,23 @@ namespace RRQMSocket.RPC.RRQMRPC
RpcContext content = RpcContext.Deserialize(byteBlock);
if (content.Feedback == 1)
{
List<byte[]> ps = content.ParametersBytes;
List<byte[]> ps = content.parametersBytes;
ByteBlock returnByteBlock = this.BytePool.GetByteBlock(this.BufferLength);
try
{
content.ParametersBytes = null;
content.parametersBytes = null;
content.Status = 1;
content.Serialize(returnByteBlock);
this.UDPSend(101, remoteEndPoint, returnByteBlock.Buffer, 0, (int)returnByteBlock.Length);
this.UDPSend(101, remoteEndPoint, returnByteBlock.Buffer, 0, returnByteBlock.Len);
}
finally
{
content.ParametersBytes = ps;
content.parametersBytes = ps;
returnByteBlock.Dispose();
}
}
this.ExecuteContext(content, remoteEndPoint);
this.ExecuteContext(content, new UdpCaller(this, remoteEndPoint));
}
catch (Exception e)
{
@@ -348,7 +423,8 @@ namespace RRQMSocket.RPC.RRQMRPC
try
{
string proxyToken = Encoding.UTF8.GetString(buffer, 2, r - 2);
UDPSend(102, remoteEndPoint, SerializeConvert.RRQMBinarySerialize(this.GetRegisteredMethodItems(proxyToken, remoteEndPoint), true));
UDPSend(102, remoteEndPoint, SerializeConvert.RRQMBinarySerialize(
this.GetRegisteredMethodItems(proxyToken, new UdpCaller(this, remoteEndPoint)), true));
}
catch (Exception e)
{
@@ -359,24 +435,36 @@ namespace RRQMSocket.RPC.RRQMRPC
}
}
#if NET45_OR_GREATER
/// <summary>
/// 编译代理
/// <inheritdoc/>
/// </summary>
/// <param name="targetDic">存放目标文件夹</param>
public void CompilerProxy(string targetDic = "")
protected override void LoadConfig(ServiceConfig ServiceConfig)
{
string assemblyInfo = CodeGenerator.GetAssemblyInfo(this.proxyInfo.AssemblyName, this.proxyInfo.Version);
List<string> codesString = new List<string>();
codesString.Add(assemblyInfo);
foreach (var item in this.proxyInfo.Codes)
{
codesString.Add(item.Code);
}
RpcCompiler.CompileCode(Path.Combine(targetDic, this.proxyInfo.AssemblyName), codesString.ToArray());
base.LoadConfig(ServiceConfig);
this.serializationSelector = (SerializationSelector)ServiceConfig.GetValue(UdpRpcParserConfig.SerializationSelectorProperty);
this.ProxyToken = (string)ServiceConfig.GetValue(UdpRpcParserConfig.ProxyTokenProperty);
this.NameSpace = (string)ServiceConfig.GetValue(UdpRpcParserConfig.NameSpaceProperty);
this.RPCVersion = (Version)ServiceConfig.GetValue(UdpRpcParserConfig.RPCVersionProperty);
}
#endif
private void UDPSend(short procotol, EndPoint endPoint, byte[] buffer, int offset, int length)
{
ByteBlock byteBlock = this.BytePool.GetByteBlock(length + 2);
try
{
byteBlock.Write(BitConverter.GetBytes(procotol));
byteBlock.Write(buffer, offset, length);
this.SendTo(byteBlock.Buffer, 0, byteBlock.Len, endPoint);
}
finally
{
byteBlock.Dispose();
}
}
private void UDPSend(short procotol, EndPoint endPoint, byte[] buffer)
{
this.UDPSend(procotol, endPoint, buffer, 0, buffer.Length);
}
}
}

View File

@@ -4,15 +4,16 @@
<ApplicationIcon>RRQM.ico</ApplicationIcon>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>RRQM.pfx</AssemblyOriginatorKeyFile>
<Version>5.5.0</Version>
<Version>5.6.0</Version>
<Company>若汝棋茗</Company>
<Copyright>Copyright © 2021 若汝棋茗</Copyright>
<Description>介绍这是一个高性能的RPC微服务框架支持异步调用、权限管理、错误状态返回、服务回调等。在空载函数执行时10万次调用仅3.8秒在不返回状态时仅0.9秒。
更新说明:
修改:服务类ServerProvider改为IServerProvider接口
修改RRQMRPC下多数含有“RPC”的类改为“Rpc”驼峰拼写
增加:序列化方式中增加JsonSerializeConverter
修改:序列化方式由客户端动态指定
增加:支持调用上下文
增加:支持客户端动态指定调用实例
增加Channel联合使用。
Demohttps://gitee.com/RRQM_OS/RRQMBox
APIhttps://gitee.com/RRQM_OS/RRQM/wikis/pages</Description>
@@ -67,6 +68,8 @@ APIhttps://gitee.com/RRQM_OS/RRQM/wikis/pages</Description>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="RRQMSocket" Version="5.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RRQMSocket\RRQMSocket.csproj" />
</ItemGroup>
</Project>