2019-07-29 02:05:05 +08:00
#Region "Microsoft.VisualBasic::d883b5e7df0927d02a228167bb2da654, Microsoft.VisualBasic.Core\Net\Protocol\Reflection\ProtocolHandler.vb"
2018-10-06 00:02:05 +08:00
2018-10-06 16:50:20 +08:00
' 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/>.
2018-10-06 02:52:23 +08:00
2018-10-06 16:50:20 +08:00
' /********************************************************************************/
2018-10-06 02:52:23 +08:00
2018-10-06 16:50:20 +08:00
' Summaries:
2018-10-06 02:52:23 +08:00
2018-10-06 16:50:20 +08:00
' Class ProtocolHandler
'
' Properties: DeclaringType, ProtocolEntry
'
' Constructor: (+1 Overloads) Sub New
' Function: GetMethod, HandlePush, HandleRequest, method1, method2
' (+2 Overloads) SafelyCreateObject, ToString
'
'
' /********************************************************************************/
2018-08-02 20:14:48 +08:00
#End Region
2018-10-06 02:52:23 +08:00
Imports System . Reflection
Imports System . Runtime . CompilerServices
2018-08-02 20:14:48 +08:00
Imports Microsoft . VisualBasic . Net . Abstract
Imports Microsoft . VisualBasic . Net . Http
2018-10-06 01:35:38 +08:00
Imports Microsoft . VisualBasic . Net . Tcp
2018-10-06 02:52:23 +08:00
Imports TcpEndPoint = System . Net . IPEndPoint
2018-08-02 20:14:48 +08:00
Namespace Net . Protocols . Reflection
''' <summary>
2018-10-06 01:35:38 +08:00
''' 这个模块只处理<see cref="DataRequestHandler"/>类型的接口
2018-10-06 02:52:23 +08:00
'''
''' ```vbnet
''' <see cref="System.Delegate"/> Function(request As <see cref="RequestStream"/>, RemoteAddress As <see cref="TcpEndPoint"/>) As <see cref="RequestStream"/>
''' ```
2018-08-02 20:14:48 +08:00
''' </summary>
Public Class ProtocolHandler : Inherits IProtocolHandler
2018-10-05 21:53:43 +08:00
Protected Protocols As Dictionary ( Of Long , DataRequestHandler )
2018-08-02 20:14:48 +08:00
''' <summary>
''' 这个类型建议一般为某种枚举类型
''' </summary>
''' <returns></returns>
2018-10-06 01:35:38 +08:00
Public ReadOnly Property DeclaringType As Type
2018-08-02 20:14:48 +08:00
Public Overrides ReadOnly Property ProtocolEntry As Long
Public Overrides Function ToString ( ) As String
Return $ " *{ProtocolEntry} ---> {DeclaringType.FullName} //{Protocols.Count} Protocols. "
End Function
2018-10-06 02:52:23 +08:00
Const AllInstanceMethod As BindingFlags =
BindingFlags . Public Or
BindingFlags . NonPublic Or
BindingFlags . Instance
2018-08-02 20:14:48 +08:00
''' <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
2018-10-06 01:35:38 +08:00
' 解析出所有符合 WrapperClassTools.Net.DataRequestHandler 接口类型的函数方法
2018-10-06 02:52:23 +08:00
Dim Methods = type . GetMethods ( bindingAttr : = AllInstanceMethod )
Dim LQuery = ( From entryPoint As MethodInfo
In Methods
2018-08-02 20:14:48 +08:00
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 )
2018-10-06 02:52:23 +08:00
Me . Protocols = LQuery . ToDictionary ( Function ( element )
Return element . Protocol . EntryPoint
End Function ,
2018-08-02 20:14:48 +08:00
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
2018-10-06 02:52:23 +08:00
<MethodImpl(MethodImplOptions.AggressiveInlining)>
2018-08-02 20:14:48 +08:00
Public Function HandlePush ( uid As Long , request As RequestStream ) As RequestStream
2018-10-05 03:16:38 +08:00
Return HandleRequest ( request , Nothing )
2018-08-02 20:14:48 +08:00
End Function
''' <summary>
2019-07-24 01:37:01 +08:00
''' Handle the data request from the client for socket events: <see cref="TcpServicesSocket.ResponseHandler"/>.
2018-08-02 20:14:48 +08:00
''' </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>
2018-10-06 02:52:23 +08:00
Public Overrides Function HandleRequest ( request As RequestStream , remoteDevcie As TcpEndPoint ) As RequestStream
2018-08-02 20:14:48 +08:00
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
2018-10-06 02:52:23 +08:00
' 没有找到相对应的协议处理逻辑,则没有实现相对应的数据协议处理方法
Return NetResponse . RFC_NOT_IMPLEMENTED
2018-08-02 20:14:48 +08:00
End If
Dim EntryPoint As DataRequestHandler = Me . Protocols ( request . Protocol )
2018-10-05 03:16:38 +08:00
Dim value As RequestStream = EntryPoint ( request , remoteDevcie )
2018-08-02 20:14:48 +08:00
Return value
End Function
2018-10-06 02:52:23 +08:00
Private Shared Function GetMethod ( obj As Object , entryPoint As MethodInfo ) As DataRequestHandler
Dim parameters As ParameterInfo ( ) = entryPoint . GetParameters
2018-08-02 20:14:48 +08:00
If Not entryPoint . ReturnType . Equals ( GetType ( RequestStream ) ) Then
Return Nothing
2018-10-06 03:47:20 +08:00
ElseIf parameters . Length > 2 Then
2018-08-02 20:14:48 +08:00
Return Nothing
End If
If parameters . Length = 0 Then
2018-10-06 02:52:23 +08:00
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 )
2018-08-02 20:14:48 +08:00
End If
2018-10-06 02:52:23 +08:00
Return Nothing
End Function
2018-08-02 20:14:48 +08:00
2018-10-06 02:52:23 +08:00
Private Shared Function method2 ( obj As Object , entryPoint As MethodInfo , parameters As ParameterInfo ( ) ) As DataRequestHandler
2018-10-06 03:47:20 +08:00
If ( Not parameters . First . ParameterType . Equals ( GetType ( RequestStream ) ) OrElse
Not parameters . Last . ParameterType . Equals ( GetType ( TcpEndPoint ) ) ) Then
2018-10-06 02:52:23 +08:00
Return Nothing
Else
Return AddressOf New ProtocolInvoker ( obj , entryPoint ) . InvokeProtocol2
2018-08-02 20:14:48 +08:00
End If
2018-10-06 02:52:23 +08:00
End Function
2018-08-02 20:14:48 +08:00
2018-10-06 02:52:23 +08:00
Private Shared Function method1 ( obj As Object , entryPoint As MethodInfo , parameters As ParameterInfo ( ) ) As DataRequestHandler
2018-10-06 03:47:20 +08:00
If Not parameters . First . ParameterType . Equals ( GetType ( RequestStream ) ) Then
2018-10-06 02:52:23 +08:00
Return Nothing
Else
Return AddressOf New ProtocolInvoker ( obj , entryPoint ) . InvokeProtocol1
2018-08-02 20:14:48 +08:00
End If
End Function
2018-10-05 03:27:47 +08:00
2018-10-06 02:52:23 +08:00
<MethodImpl(MethodImplOptions.AggressiveInlining)>
2018-10-05 03:27:47 +08:00
Public Shared Narrowing Operator CType ( handler As ProtocolHandler ) As DataRequestHandler
Return AddressOf handler . HandleRequest
End Operator
2018-08-02 20:14:48 +08:00
End Class
End Namespace