//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在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 // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Collections.Concurrent; using System.IO; using System.Net; using System.Threading; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; namespace TouchSocket.Rpc.TouchRpc { /// /// UDP Rpc解释器 /// public partial class UdpTouchRpc : UdpSessionBase, IUdpTouchRpc { private readonly ActionMap m_actionMap; private readonly Timer m_timer; private readonly ConcurrentDictionary m_udpRpcActors; private RpcStore m_rpcStore; private SerializationSelector m_serializationSelector; /// /// 构造函数 /// public UdpTouchRpc() { m_timer = new Timer((obj) => { m_udpRpcActors.Remove((kv) => { if (--kv.Value.Tick < 0) { return true; } return false; }); }, null, 1000 * 30, 1000 * 30); m_actionMap = new ActionMap(); m_udpRpcActors = new ConcurrentDictionary(); } /// /// 方法映射表 /// public ActionMap ActionMap { get => m_actionMap; } /// /// 不需要握手,所以此值一直为True。 /// public bool IsHandshaked => true; string IRpcActor.RootPath { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } /// public RpcActor RpcActor => GetUdpRpcActor(); /// public RpcStore RpcStore => m_rpcStore; /// public SerializationSelector SerializationSelector => m_serializationSelector; /// public Func TryCanInvoke { get; set; } bool IRpcActor.ChannelExisted(int id) { throw new NotImplementedException(); } Channel IRpcActor.CreateChannel() { throw new NotImplementedException(); } Channel IRpcActor.CreateChannel(int id) { throw new NotImplementedException(); } Channel ITargetRpcActor.CreateChannel(string targetId) { throw new NotImplementedException(); } Channel ITargetRpcActor.CreateChannel(string targetId, int id) { throw new NotImplementedException(); } /// public void Invoke(string method, IInvokeOption invokeOption, params object[] parameters) { GetUdpRpcActor().Invoke(method, invokeOption, parameters); } /// public T Invoke(string method, IInvokeOption invokeOption, params object[] parameters) { return GetUdpRpcActor().Invoke(method, invokeOption, parameters); } /// public T Invoke(string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { return GetUdpRpcActor().Invoke(method, invokeOption, ref parameters, types); } /// public void Invoke(string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { GetUdpRpcActor().Invoke(method, invokeOption, ref parameters, types); } void ITargetRpcClient.Invoke(string targetId, string method, IInvokeOption invokeOption, params object[] parameters) { throw new NotImplementedException(); } T ITargetRpcClient.Invoke(string targetId, string method, IInvokeOption invokeOption, params object[] parameters) { throw new NotImplementedException(); } void ITargetRpcClient.Invoke(string targetId, string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { throw new NotImplementedException(); } T ITargetRpcClient.Invoke(string targetId, string method, IInvokeOption invokeOption, ref object[] parameters, Type[] types) { throw new NotImplementedException(); } /// public Task InvokeAsync(string method, IInvokeOption invokeOption, params object[] parameters) { return GetUdpRpcActor().InvokeAsync(method, invokeOption, parameters); } /// public Task InvokeAsync(string method, IInvokeOption invokeOption, params object[] parameters) { return GetUdpRpcActor().InvokeAsync(method, invokeOption, parameters); } #region RPC解析器 void IRpcParser.OnRegisterServer(MethodInstance[] methodInstances) { foreach (var methodInstance in methodInstances) { if (methodInstance.GetAttribute() is TouchRpcAttribute attribute) { m_actionMap.Add(attribute.GetInvokenKey(methodInstance), methodInstance); } } } void IRpcParser.OnUnregisterServer(MethodInstance[] methodInstances) { foreach (var methodInstance in methodInstances) { if (methodInstance.GetAttribute() is TouchRpcAttribute attribute) { m_actionMap.Remove(attribute.GetInvokenKey(methodInstance)); } } } void IRpcParser.SetRpcStore(RpcStore rpcService) { m_rpcStore = rpcService; } #endregion RPC解析器 Task ITargetRpcClient.InvokeAsync(string targetId, string method, IInvokeOption invokeOption, params object[] parameters) { throw new NotImplementedException(); } Task ITargetRpcClient.InvokeAsync(string targetId, string method, IInvokeOption invokeOption, params object[] parameters) { throw new NotImplementedException(); } /// public bool Ping(int timeout = 5000) { return GetUdpRpcActor().Ping(timeout); } bool ITargetRpcActor.Ping(string targetId, int timeout) { throw new NotImplementedException(); } Result IRpcActor.PullFile(FileOperator fileOperator) { throw new NotImplementedException(); } Result ITargetRpcActor.PullFile(string targetId, FileOperator fileOperator) { throw new NotImplementedException(); } Task IRpcActor.PullFileAsync(FileOperator fileOperator) { throw new NotImplementedException(); } Task ITargetRpcActor.PullFileAsync(string targetId, FileOperator fileOperator) { throw new NotImplementedException(); } PullSmallFileResult IRpcActor.PullSmallFile(string path, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } PullSmallFileResult ITargetRpcActor.PullSmallFile(string targetId, string path, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Task IRpcActor.PullSmallFileAsync(string path, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Task ITargetRpcActor.PullSmallFileAsync(string targetId, string path, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Result IRpcActor.PushFile(FileOperator fileOperator) { throw new NotImplementedException(); } Result ITargetRpcActor.PushFile(string targetId, FileOperator fileOperator) { throw new NotImplementedException(); } Task IRpcActor.PushFileAsync(FileOperator fileOperator) { throw new NotImplementedException(); } Task ITargetRpcActor.PushFileAsync(string targetId, FileOperator fileOperator) { throw new NotImplementedException(); } Result IRpcActor.PushSmallFile(string savePath, FileInfo fileInfo, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Result ITargetRpcActor.PushSmallFile(string targetId, string savePath, FileInfo fileInfo, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Task IRpcActor.PushSmallFileAsync(string savePath, FileInfo fileInfo, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } Task ITargetRpcActor.PushSmallFileAsync(string targetId, string savePath, FileInfo fileInfo, Metadata metadata, int timeout, CancellationToken token) { throw new NotImplementedException(); } void IRpcActor.ResetID(string newID) { throw new NotImplementedException(); } /// public void Send(short protocol, byte[] buffer, int offset, int length) { GetUdpRpcActor().Send(protocol, buffer, offset, length); } /// public Task SendAsync(short protocol, byte[] buffer, int offset, int length) { return GetUdpRpcActor().SendAsync(protocol, buffer, offset, length); } Result IRpcActor.SendStream(Stream stream, StreamOperator streamOperator, Metadata metadata) { throw new NotImplementedException(); } Task IRpcActor.SendStreamAsync(Stream stream, StreamOperator streamOperator, Metadata metadata) { throw new NotImplementedException(); } bool IRpcActor.TrySubscribeChannel(int id, out Channel channel) { throw new NotImplementedException(); } /// protected override void Dispose(bool disposing) { m_timer.SafeDispose(); m_udpRpcActors.Clear(); base.Dispose(disposing); } /// protected override void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo) { GetUdpRpcActor(remoteEndPoint).InputReceivedData(byteBlock); } /// protected override void LoadConfig(TouchSocketConfig config) { m_serializationSelector = config.GetValue(TouchRpcConfigExtensions.SerializationSelectorProperty); if (config.GetValue(RpcConfigExtensions.RpcStoreProperty) is RpcStore rpcStore) { rpcStore.AddRpcParser(GetType().Name, this); } else { new RpcStore(config.Container).AddRpcParser(GetType().Name, this); } base.LoadConfig(config); } private MethodInstance GetInvokeMethod(string arg) { return m_actionMap.GetMethodInstance(arg); } private UdpRpcActor GetUdpRpcActor(EndPoint endPoint) { if (!m_udpRpcActors.TryGetValue(endPoint, out UdpRpcActor udpRpcActor)) { udpRpcActor = new UdpRpcActor(this, endPoint, Container.Resolve()) { Caller = new UdpCaller(this, endPoint), RpcStore = m_rpcStore, GetInvokeMethod = GetInvokeMethod, SerializationSelector = m_serializationSelector }; m_udpRpcActors.TryAdd(endPoint, udpRpcActor); } udpRpcActor.Tick++; return udpRpcActor; } private UdpRpcActor GetUdpRpcActor() { if (RemoteIPHost == null) { throw new ArgumentNullException(nameof(RemoteIPHost)); } return GetUdpRpcActor(RemoteIPHost.EndPoint); } } }