207 lines
8.5 KiB
VB.net
207 lines
8.5 KiB
VB.net
#Region "Microsoft.VisualBasic::d883b5e7df0927d02a228167bb2da654, Microsoft.VisualBasic.Core\Net\Protocol\Reflection\ProtocolHandler.vb"
|
|
|
|
' Author:
|
|
'
|
|
' asuka (amethyst.asuka@gcmodeller.org)
|
|
' xie (genetics@smrucc.org)
|
|
' xieguigang (xie.guigang@live.com)
|
|
'
|
|
' Copyright (c) 2018 GPL3 Licensed
|
|
'
|
|
'
|
|
' GNU GENERAL PUBLIC LICENSE (GPL3)
|
|
'
|
|
'
|
|
' This program is free software: you can redistribute it and/or modify
|
|
' it under the terms of the GNU General Public License as published by
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
' (at your option) any later version.
|
|
'
|
|
' This program is distributed in the hope that it will be useful,
|
|
' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
' GNU General Public License for more details.
|
|
'
|
|
' You should have received a copy of the GNU General Public License
|
|
' along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
' Summaries:
|
|
|
|
' Class ProtocolHandler
|
|
'
|
|
' Properties: DeclaringType, ProtocolEntry
|
|
'
|
|
' Constructor: (+1 Overloads) Sub New
|
|
' Function: GetMethod, HandlePush, HandleRequest, method1, method2
|
|
' (+2 Overloads) SafelyCreateObject, ToString
|
|
'
|
|
'
|
|
' /********************************************************************************/
|
|
|
|
#End Region
|
|
|
|
Imports System.Reflection
|
|
Imports System.Runtime.CompilerServices
|
|
Imports Microsoft.VisualBasic.Net.Abstract
|
|
Imports Microsoft.VisualBasic.Net.Http
|
|
Imports Microsoft.VisualBasic.Net.Tcp
|
|
Imports TcpEndPoint = System.Net.IPEndPoint
|
|
|
|
Namespace Net.Protocols.Reflection
|
|
|
|
''' <summary>
|
|
''' 这个模块只处理<see cref="DataRequestHandler"/>类型的接口
|
|
'''
|
|
''' ```vbnet
|
|
''' <see cref="System.Delegate"/> Function(request As <see cref="RequestStream"/>, RemoteAddress As <see cref="TcpEndPoint"/>) As <see cref="RequestStream"/>
|
|
''' ```
|
|
''' </summary>
|
|
Public Class ProtocolHandler : Inherits IProtocolHandler
|
|
|
|
Protected Protocols As Dictionary(Of Long, DataRequestHandler)
|
|
''' <summary>
|
|
''' 这个类型建议一般为某种枚举类型
|
|
''' </summary>
|
|
''' <returns></returns>
|
|
Public ReadOnly Property DeclaringType As Type
|
|
Public Overrides ReadOnly Property ProtocolEntry As Long
|
|
|
|
Public Overrides Function ToString() As String
|
|
Return $"*{ProtocolEntry} ---> {DeclaringType.FullName} //{Protocols.Count} Protocols."
|
|
End Function
|
|
|
|
Const AllInstanceMethod As BindingFlags =
|
|
BindingFlags.Public Or
|
|
BindingFlags.NonPublic Or
|
|
BindingFlags.Instance
|
|
|
|
''' <summary>
|
|
''' 请注意,假若没有在目标的类型定义之中查找出入口点的定义,则这个构造函数会报错,
|
|
''' 假若需要安全的创建对象,可以使用<see cref="ProtocolHandler.SafelyCreateObject(Of T)(T)"/>函数
|
|
''' </summary>
|
|
''' <param name="obj">Protocol的实例</param>
|
|
Sub New(obj As Object)
|
|
Dim type As Type = obj.GetType
|
|
Dim entry As Protocol = Protocol.GetProtocolCategory(type)
|
|
|
|
Me.DeclaringType = entry?.DeclaringType
|
|
Me.ProtocolEntry = entry?.EntryPoint
|
|
|
|
' 解析出所有符合 WrapperClassTools.Net.DataRequestHandler 接口类型的函数方法
|
|
Dim Methods = type.GetMethods(bindingAttr:=AllInstanceMethod)
|
|
Dim LQuery = (From entryPoint As MethodInfo
|
|
In Methods
|
|
Let Protocol As Protocol = Protocol.GetEntryPoint(entryPoint)
|
|
Let method As DataRequestHandler = GetMethod(obj, entryPoint)
|
|
Where Not (Protocol Is Nothing) AndAlso
|
|
Not method Is Nothing
|
|
Select Protocol, entryPoint, method)
|
|
|
|
Me.Protocols = LQuery.ToDictionary(Function(element)
|
|
Return element.Protocol.EntryPoint
|
|
End Function,
|
|
Function(element) element.method)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' 失败会返回空值
|
|
''' </summary>
|
|
''' <typeparam name="T"></typeparam>
|
|
''' <param name="App"></param>
|
|
''' <returns></returns>
|
|
Public Shared Function SafelyCreateObject(Of T As Class)(App As T) As ProtocolHandler
|
|
Try
|
|
Return New ProtocolHandler(App)
|
|
Catch ex As Exception
|
|
Return Nothing
|
|
End Try
|
|
End Function
|
|
|
|
Public Shared Function SafelyCreateObject(App As Object) As ProtocolHandler
|
|
Try
|
|
Return New ProtocolHandler(App)
|
|
Catch ex As Exception
|
|
Return Nothing
|
|
End Try
|
|
End Function
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
Public Function HandlePush(uid As Long, request As RequestStream) As RequestStream
|
|
Return HandleRequest(request, Nothing)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Handle the data request from the client for socket events: <see cref="TcpServicesSocket.ResponseHandler"/>.
|
|
''' </summary>
|
|
''' <param name="request">The request stream object which contains the commands from the client</param>
|
|
''' <param name="remoteDevcie">The IPAddress of the target incoming client data request.</param>
|
|
''' <returns></returns>
|
|
Public Overrides Function HandleRequest(request As RequestStream, remoteDevcie As TcpEndPoint) As RequestStream
|
|
If request.ProtocolCategory <> Me.ProtocolEntry Then
|
|
#If DEBUG Then
|
|
Call $"Protocol_entry:={request.ProtocolCategory} was not found!".__DEBUG_ECHO
|
|
#End If
|
|
Return NetResponse.RFC_VERSION_NOT_SUPPORTED
|
|
End If
|
|
|
|
If Not Me.Protocols.ContainsKey(request.Protocol) Then
|
|
#If DEBUG Then
|
|
Call $"Protocol:={request.Protocol} was not found!".__DEBUG_ECHO
|
|
#End If
|
|
' 没有找到相对应的协议处理逻辑,则没有实现相对应的数据协议处理方法
|
|
Return NetResponse.RFC_NOT_IMPLEMENTED
|
|
End If
|
|
|
|
Dim EntryPoint As DataRequestHandler = Me.Protocols(request.Protocol)
|
|
Dim value As RequestStream = EntryPoint(request, remoteDevcie)
|
|
Return value
|
|
End Function
|
|
|
|
Private Shared Function GetMethod(obj As Object, entryPoint As MethodInfo) As DataRequestHandler
|
|
Dim parameters As ParameterInfo() = entryPoint.GetParameters
|
|
|
|
If Not entryPoint.ReturnType.Equals(GetType(RequestStream)) Then
|
|
Return Nothing
|
|
ElseIf parameters.Length > 2 Then
|
|
Return Nothing
|
|
End If
|
|
|
|
If parameters.Length = 0 Then
|
|
Return AddressOf New ProtocolInvoker(obj, entryPoint).InvokeProtocol0
|
|
ElseIf parameters.Length = 1 Then
|
|
Return method1(obj, entryPoint, parameters)
|
|
ElseIf parameters.Length = 2 Then
|
|
Return method2(obj, entryPoint, parameters)
|
|
End If
|
|
|
|
Return Nothing
|
|
End Function
|
|
|
|
Private Shared Function method2(obj As Object, entryPoint As MethodInfo, parameters As ParameterInfo()) As DataRequestHandler
|
|
If (Not parameters.First.ParameterType.Equals(GetType(RequestStream)) OrElse
|
|
Not parameters.Last.ParameterType.Equals(GetType(TcpEndPoint))) Then
|
|
Return Nothing
|
|
Else
|
|
Return AddressOf New ProtocolInvoker(obj, entryPoint).InvokeProtocol2
|
|
End If
|
|
End Function
|
|
|
|
Private Shared Function method1(obj As Object, entryPoint As MethodInfo, parameters As ParameterInfo()) As DataRequestHandler
|
|
If Not parameters.First.ParameterType.Equals(GetType(RequestStream)) Then
|
|
Return Nothing
|
|
Else
|
|
Return AddressOf New ProtocolInvoker(obj, entryPoint).InvokeProtocol1
|
|
End If
|
|
End Function
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
|
Public Shared Narrowing Operator CType(handler As ProtocolHandler) As DataRequestHandler
|
|
Return AddressOf handler.HandleRequest
|
|
End Operator
|
|
End Class
|
|
End Namespace
|