未完结更新

This commit is contained in:
御风踏青岚
2021-05-19 17:29:32 +08:00
parent 6b959e5a88
commit cf61ade7cf
10 changed files with 386 additions and 7 deletions

View File

@@ -0,0 +1,43 @@
//------------------------------------------------------------------------------
// 此代码版权归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按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.JsonRpc
{
/// <summary>
/// 适用于XmlRpc的标记
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class JsonRpcAttribute : RPCMethodAttribute
{
/// <summary>
/// 构造函数
/// </summary>
public JsonRpcAttribute()
{
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="methodKey"></param>
public JsonRpcAttribute(string methodKey)
{
this.MethodKey = methodKey;
}
/// <summary>
/// 服务唯一标识
/// </summary>
public string MethodKey { get; private set; }
}
}

View File

@@ -0,0 +1,70 @@
//------------------------------------------------------------------------------
// 此代码版权归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按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.Collections;
using System.Collections.Generic;
namespace RRQMSocket.RPC.JsonRpc
{
/// <summary>
/// 服务映射图
/// </summary>
public class ActionMap: IEnumerable<KeyValuePair<string, MethodInstance>>
{
internal ActionMap()
{
this.actionMap = new Dictionary<string, MethodInstance>();
}
private Dictionary<string, MethodInstance> actionMap;
internal void Add(string actionKey, MethodInstance methodInstance)
{
this.actionMap.Add(actionKey, methodInstance);
}
/// <summary>
/// 服务键集合
/// </summary>
public IEnumerable<string> ActionKeys { get { return this.actionMap.Keys; } }
/// <summary>
/// 通过routeUrl获取函数实例
/// </summary>
/// <param name="actionKey"></param>
/// <param name="methodInstance"></param>
/// <returns></returns>
public bool TryGet(string actionKey, out MethodInstance methodInstance)
{
if (this.actionMap.ContainsKey(actionKey))
{
methodInstance = this.actionMap[actionKey];
return true;
}
methodInstance = null;
return false;
}
/// <summary>
/// 返回迭代器
/// </summary>
/// <returns></returns>
public IEnumerator<KeyValuePair<string, MethodInstance>> GetEnumerator()
{
return this.actionMap.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.actionMap.GetEnumerator();
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RRQMSocket.RPC.JsonRpc
{
/// <summary>
/// JsonRpc调用器
/// </summary>
public class RpcRequestContext
{
#pragma warning disable CS1591
public string jsonrpc;
public string method;
public object[] @params;
public string id;
#pragma warning restore CS1591
}
}

View File

@@ -0,0 +1,245 @@
//------------------------------------------------------------------------------
// 此代码版权归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议若本仓库没有设置则按MIT开源协议授权
// CSDN博客https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频https://space.bilibili.com/94253567
// Gitee源代码仓库https://gitee.com/RRQM_Home
// Github源代码仓库https://github.com/RRQM
// 交流QQ群234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using RRQMCore.ByteManager;
using RRQMCore.Exceptions;
using RRQMCore.Log;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Json;
using System.Text;
namespace RRQMSocket.RPC.JsonRpc
{
/// <summary>
/// WebApi解析器
/// </summary>
public class JsonRpcParser : RPCParser, IService
{
/// <summary>
/// 构造函数
/// </summary>
public JsonRpcParser()
{
this.tcpService = new RRQMTcpService();
this.actionMap = new ActionMap();
this.tcpService.CreatSocketCliect += this.OnCreatSocketCliect;
this.tcpService.OnReceived += this.OnReceived;
}
/// <summary>
/// 在初次接收时
/// </summary>
/// <param name="socketClient"></param>
/// <param name="creatOption"></param>
private void OnCreatSocketCliect(RRQMSocketClient socketClient, CreatOption creatOption)
{
if (creatOption.NewCreate)
{
socketClient.DataHandlingAdapter = new TerminatorDataHandlingAdapter(this.BufferLength, "\r\n");
}
}
private RRQMTcpService tcpService;
/// <summary>
/// 函数键映射图
/// </summary>
public ActionMap ActionMap { get { return this.actionMap; } }
private ActionMap actionMap;
/// <summary>
/// 获取当前服务通信器
/// </summary>
public RRQMTcpService Service { get { return this.tcpService; } }
/// <summary>
/// 获取绑定状态
/// </summary>
public bool IsBind => this.tcpService.IsBind;
/// <summary>
/// 获取或设置缓存大小
/// </summary>
public int BufferLength { get { return this.tcpService.BufferLength; } set { this.tcpService.BufferLength = value; } }
/// <summary>
/// 获取内存池实例
/// </summary>
public BytePool BytePool => this.tcpService.BytePool;
/// <summary>
/// 获取或设置日志记录器
/// </summary>
public ILog Logger { get { return this.tcpService.Logger; } set { this.tcpService.Logger = value; } }
/// <summary>
/// 绑定服务
/// </summary>
/// <param name="port">端口号</param>
/// <param name="threadCount">多线程数量</param>
/// <exception cref="RRQMException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public void Bind(int port, int threadCount = 1)
{
this.tcpService.Bind(port, threadCount);
}
/// <summary>
/// 绑定服务
/// </summary>
/// <param name="iPHost">ip和端口号格式如“127.0.0.1:7789”。IP可输入Ipv6</param>
/// <param name="threadCount">多线程数量</param>
/// <exception cref="RRQMException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public void Bind(IPHost iPHost, int threadCount)
{
this.tcpService.Bind(iPHost, threadCount);
}
/// <summary>
/// 绑定服务
/// </summary>
/// <param name="addressFamily">寻址方案</param>
/// <param name="endPoint">绑定节点</param>
/// <param name="threadCount">多线程数量</param>
/// <exception cref="RRQMException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public void Bind(AddressFamily addressFamily, EndPoint endPoint, int threadCount)
{
this.tcpService.Bind(addressFamily, endPoint, threadCount);
}
private void OnReceived(RRQMSocketClient socketClient, ByteBlock byteBlock, object obj)
{
MethodInvoker methodInvoker = new MethodInvoker();
methodInvoker.Flag = socketClient;
MethodInstance methodInstance = null;
try
{
RpcRequestContext context = this.BuildRequestContext(byteBlock, out methodInstance);
if (methodInstance == null)
{
methodInvoker.Status = InvokeStatus.UnFound;
}
else if (methodInstance.IsEnable)
{
methodInvoker.Parameters = context.@params;
}
else
{
methodInvoker.Status = InvokeStatus.UnEnable;
}
}
catch (Exception ex)
{
methodInvoker.Status = InvokeStatus.Exception;
methodInvoker.StatusMessage = ex.Message;
}
this.ExecuteMethod(methodInvoker, methodInstance);
}
/// <summary>
/// 结束调用
/// </summary>
/// <param name="methodInvoker"></param>
/// <param name="methodInstance"></param>
protected sealed override void EndInvokeMethod(MethodInvoker methodInvoker, MethodInstance methodInstance)
{
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="methodInstances"></param>
protected sealed override void InitializeServers(MethodInstance[] methodInstances)
{
foreach (var methodInstance in methodInstances)
{
foreach (var att in methodInstance.RPCAttributes)
{
if (att is JsonRpcAttribute attribute)
{
if (methodInstance.IsByRef)
{
throw new RRQMRPCException("JsonRpc服务中不允许有out及ref关键字");
}
string actionKey = string.IsNullOrEmpty(attribute.MethodKey) ? methodInstance.Method.Name : attribute.MethodKey;
try
{
this.actionMap.Add(actionKey, methodInstance);
}
catch
{
throw new RRQMRPCException($"函数键为{actionKey}的方法已注册。");
}
}
}
}
}
/// <summary>
/// 构建请求内容
/// </summary>
/// <param name="byteBlock">数据</param>
/// <param name="methodInstance">调用服务实例</param>
/// <returns></returns>
protected virtual RpcRequestContext BuildRequestContext(ByteBlock byteBlock, out MethodInstance methodInstance)
{
byteBlock.Seek(0, SeekOrigin.Begin);
RpcRequestContext context = (RpcRequestContext)ReadObject(typeof(RpcRequestContext), byteBlock);
if (this.actionMap.TryGet(context.method, out methodInstance))
{
if (context.@params != null)
{
for (int i = 0; i < context.@params.Length; i++)
{
string s = context.@params[i].ToString();
MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(s));
memoryStream.Seek(0, SeekOrigin.Begin);
context.@params[i] = ReadObject(methodInstance.ParameterTypes[i], memoryStream);
}
}
}
else
{
methodInstance = null;
}
return context;
}
private object ReadObject(Type type, Stream stream)
{
DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(RpcRequestContext));
return deseralizer.ReadObject(stream);
}
/// <summary>
/// 释放资源
/// </summary>
public override void Dispose()
{
this.tcpService.Dispose();
}
}
}

View File

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 244 KiB

View File

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

View File

@@ -70,6 +70,6 @@
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RRQMSocket\RRQMSocket.csproj" />
<PackageReference Include="RRQMSocket.RPC" Version="1.0.6" />
</ItemGroup>
</Project>

View File

@@ -16,7 +16,7 @@ namespace RRQMSocket.RPC.XmlRpc
/// <summary>
/// 适用于XmlRpc的标记
/// </summary>
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class XmlRpcAttribute : RPCMethodAttribute
{
/// <summary>

View File

@@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RRQMSocket.RPC.WebApi", "RR
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RRQMSocket.RPC.XmlRpc", "RRQMSocket.RPC.XmlRpc\RRQMSocket.RPC.XmlRpc.csproj", "{7A7EFF80-EBDD-4205-901F-B8F4C22307DF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RRQMSocket.JsonRpc", "RRQMSocket.Json\RRQMSocket.JsonRpc.csproj", "{9E5DDC4E-4C72-4AD0-B3FF-404391B8B2CF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RRQMSocket.RPC.JsonRpc", "RRQMSocket.RPC.JsonRpc\RRQMSocket.RPC.JsonRpc.csproj", "{0E36E1FE-49AB-4F69-86AB-710E2AD880D8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -47,10 +47,10 @@ Global
{7A7EFF80-EBDD-4205-901F-B8F4C22307DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A7EFF80-EBDD-4205-901F-B8F4C22307DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A7EFF80-EBDD-4205-901F-B8F4C22307DF}.Release|Any CPU.Build.0 = Release|Any CPU
{9E5DDC4E-4C72-4AD0-B3FF-404391B8B2CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E5DDC4E-4C72-4AD0-B3FF-404391B8B2CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E5DDC4E-4C72-4AD0-B3FF-404391B8B2CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E5DDC4E-4C72-4AD0-B3FF-404391B8B2CF}.Release|Any CPU.Build.0 = Release|Any CPU
{0E36E1FE-49AB-4F69-86AB-710E2AD880D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E36E1FE-49AB-4F69-86AB-710E2AD880D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E36E1FE-49AB-4F69-86AB-710E2AD880D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E36E1FE-49AB-4F69-86AB-710E2AD880D8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE