mirror of
https://github.com/RRQM/TouchSocket.git
synced 2025-12-19 09:56:44 +08:00
未完结更新
This commit is contained in:
43
RRQMSocket.RPC.JsonRpc/Attribute/JsonRpcAttribute.cs
Normal file
43
RRQMSocket.RPC.JsonRpc/Attribute/JsonRpcAttribute.cs
Normal 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; }
|
||||
}
|
||||
}
|
||||
70
RRQMSocket.RPC.JsonRpc/Control/ActionMap.cs
Normal file
70
RRQMSocket.RPC.JsonRpc/Control/ActionMap.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
RRQMSocket.RPC.JsonRpc/Control/RpcRequestContext.cs
Normal file
21
RRQMSocket.RPC.JsonRpc/Control/RpcRequestContext.cs
Normal 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
|
||||
}
|
||||
}
|
||||
245
RRQMSocket.RPC.JsonRpc/Parser/JsonRpcParser.cs
Normal file
245
RRQMSocket.RPC.JsonRpc/Parser/JsonRpcParser.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 121 KiB |
@@ -70,6 +70,6 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RRQMSocket\RRQMSocket.csproj" />
|
||||
<PackageReference Include="RRQMSocket.RPC" Version="1.0.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user