mirror of
https://github.com/RRQM/TouchSocket.git
synced 2025-12-19 18:06:45 +08:00
修改:序列化方式由客户端动态指定。
增加:支持调用上下文。 增加:支持客户端动态指定调用实例。 增加:Channel联合使用。
This commit is contained in:
@@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
133
RRQMSocket.RPC/Global/Commond/GlobalTools.cs
Normal file
133
RRQMSocket.RPC/Global/Commond/GlobalTools.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
29
RRQMSocket.RPC/Global/Enum/InvokeType.cs
Normal file
29
RRQMSocket.RPC/Global/Enum/InvokeType.cs
Normal 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
|
||||
}
|
||||
}
|
||||
25
RRQMSocket.RPC/Global/Enum/MethodFlags.cs
Normal file
25
RRQMSocket.RPC/Global/Enum/MethodFlags.cs
Normal 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
|
||||
}
|
||||
}
|
||||
16
RRQMSocket.RPC/Global/Interface/ICaller.cs
Normal file
16
RRQMSocket.RPC/Global/Interface/ICaller.cs
Normal 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
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
15
RRQMSocket.RPC/Global/Interface/IRpcContext.cs
Normal file
15
RRQMSocket.RPC/Global/Interface/IRpcContext.cs
Normal 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
|
||||
{
|
||||
}
|
||||
}
|
||||
28
RRQMSocket.RPC/Global/Interface/IServerCallContext.cs
Normal file
28
RRQMSocket.RPC/Global/Interface/IServerCallContext.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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("}");//类结束
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
140
RRQMSocket.RPC/RRQMRPC/Common/RRQMRPCTools.cs
Normal file
140
RRQMSocket.RPC/RRQMRPC/Common/RRQMRPCTools.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
RRQMSocket.RPC/RRQMRPC/Common/RpcServerCallContext.cs
Normal file
30
RRQMSocket.RPC/RRQMRPC/Common/RpcServerCallContext.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
47
RRQMSocket.RPC/RRQMRPC/Common/UdpCaller.cs
Normal file
47
RRQMSocket.RPC/RRQMRPC/Common/UdpCaller.cs
Normal 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; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
/// 代理源文件命名空间
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ namespace RRQMSocket.RPC.RRQMRPC
|
||||
/// <summary>
|
||||
/// 序列化生成器
|
||||
/// </summary>
|
||||
SerializeConverter SerializeConverter { get; }
|
||||
SerializationSelector SerializationSelector { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取远程服务器RPC服务文件
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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("未指定的序列化方式");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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("未找到该客户端");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
/// 密封数据
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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联合使用。
|
||||
|
||||
Demo:https://gitee.com/RRQM_OS/RRQMBox
|
||||
API:https://gitee.com/RRQM_OS/RRQM/wikis/pages</Description>
|
||||
@@ -67,6 +68,8 @@ API:https://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>
|
||||
|
||||
Reference in New Issue
Block a user