1 #Region "Microsoft.VisualBasic::bf3e3e62bb95b64355777782b4175059, Microsoft.VisualBasic.Core\ApplicationServices\Tools\Network\Protocol\Reflection\ProtocolHandler.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class ProtocolHandler
35     
36     '         Properties: DeclaringType, ProtocolEntry
37     
38     '         Constructor: (+1 OverloadsSub New
39     '         FunctionGetMethod, HandlePush, HandleRequest, (+2 Overloads) SafelyCreateObject, ToString
40     
41     
42     ' /********************************************************************************/
43
44 #End Region
45
46 Imports System.Net
47 Imports Microsoft.VisualBasic.Net.Abstract
48 Imports Microsoft.VisualBasic.Net.Http
49
50 Namespace Net.Protocols.Reflection
51
52     ''' <summary>
53     ''' 这个模块只处理<see cref="Net.Abstract.DataRequestHandler"/>类型的接口
54     ''' </summary>
55     Public Class ProtocolHandler : Inherits IProtocolHandler
56
57         Protected Protocols As Dictionary(Of Long, Net.Abstract.DataRequestHandler)
58         ''' <summary>
59         ''' 这个类型建议一般为某种枚举类型
60         ''' </summary>
61         ''' <returns></returns>
62         Public ReadOnly Property DeclaringType As System.Type
63         Public Overrides ReadOnly Property ProtocolEntry As Long
64
65         Public Overrides Function ToString() As String
66             Return $"*{ProtocolEntry}   ---> {DeclaringType.FullName}  //{Protocols.Count} Protocols."
67         End Function
68
69         ''' <summary>
70         ''' 请注意,假若没有在目标的类型定义之中查找出入口点的定义,则这个构造函数会报错,
71         ''' 假若需要安全的创建对象,可以使用<see cref="ProtocolHandler.SafelyCreateObject(Of T)(T)"/>函数
72         ''' </summary>
73         ''' <param name="obj">Protocol的实例</param>
74         Sub New(obj As Object)
75             Dim type As Type = obj.GetType
76             Dim entry As Protocol = Protocol.GetProtocolCategory(type)
77
78             Me.DeclaringType = entry?.DeclaringType
79             Me.ProtocolEntry = entry?.EntryPoint
80             ' 解析出所有符合 WrapperClassTools.Net.DataRequestHandler 接口类型的函数方法
81
82             Dim Methods = type.GetMethods(System.Reflection.BindingFlags.Public Or
83                                           System.Reflection.BindingFlags.NonPublic Or
84                                           System.Reflection.BindingFlags.Instance)
85             Dim LQuery = (From entryPoint In Methods.AsParallel
86                           Let Protocol As Protocol = Protocol.GetEntryPoint(entryPoint)
87                           Let method As DataRequestHandler = GetMethod(obj, entryPoint)
88                           Where Not (Protocol Is NothingAndAlso
89                               Not method Is Nothing
90                           Select Protocol, entryPoint, method)
91
92             Me.Protocols = LQuery.ToDictionary(Function(element) element.Protocol.EntryPoint,
93                                                Function(element) element.method)
94         End Sub
95
96         ''' <summary>
97         ''' 失败会返回空值
98         ''' </summary>
99         ''' <typeparam name="T"></typeparam>
100         ''' <param name="App"></param>
101         ''' <returns></returns>
102         Public Shared Function SafelyCreateObject(Of T As Class)(App As T) As ProtocolHandler
103             Try
104                 Return New ProtocolHandler(App)
105             Catch ex As Exception
106                 Return Nothing
107             End Try
108         End Function
109
110         Public Shared Function SafelyCreateObject(App As ObjectAs ProtocolHandler
111             Try
112                 Return New ProtocolHandler(App)
113             Catch ex As Exception
114                 Return Nothing
115             End Try
116         End Function
117
118         Public Function HandlePush(uid As Long, request As RequestStream) As RequestStream
119             Return HandleRequest(uid, request, Nothing)
120         End Function
121
122         ''' <summary>
123         ''' Handle the data request from the client for socket events: <see cref="Net.TcpSynchronizationServicesSocket.Responsehandler"/> or <see cref="Net.SSL.SSLSynchronizationServicesSocket.Responsehandler"/>
124         ''' </summary>
125         ''' <param name="CA"></param>
126         ''' <param name="request">The request stream object which contains the commands from the client</param>
127         ''' <param name="remoteDevcie">The IPAddress of the target incoming client data request.</param>
128         ''' <returns></returns>
129         Public Overrides Function HandleRequest(CA As Long, request As RequestStream, remoteDevcie As System.Net.IPEndPoint) As RequestStream
130             If request.ProtocolCategory <> Me.ProtocolEntry Then
131 #If DEBUG Then
132                 Call $"Protocol_entry:={request.ProtocolCategory} was not found!".__DEBUG_ECHO
133 #End If
134                 Return NetResponse.RFC_VERSION_NOT_SUPPORTED
135             End If
136
137             If Not Me.Protocols.ContainsKey(request.Protocol) Then
138 #If DEBUG Then
139                 Call $"Protocol:={request.Protocol} was not found!".__DEBUG_ECHO
140 #End If
141                 Return NetResponse.RFC_NOT_IMPLEMENTED  ' 没有找到相对应的协议处理逻辑,则没有实现相对应的数据协议处理方法
142             End If
143
144             Dim EntryPoint As DataRequestHandler = Me.Protocols(request.Protocol)
145             Dim value As RequestStream = EntryPoint(CA, request, remoteDevcie)
146             Return value
147         End Function
148
149         Private Shared Function GetMethod(obj As Object, entryPoint As System.Reflection.MethodInfo) As Net.Abstract.DataRequestHandler
150             Dim parameters As System.Reflection.ParameterInfo() = entryPoint.GetParameters
151
152             If Not entryPoint.ReturnType.Equals(GetType(RequestStream)) Then
153                 Return Nothing
154             End If
155
156             If parameters.Length > 3 Then
157                 Return Nothing
158             End If
159
160             If parameters.Length = 0 Then
161                 Return AddressOf New __protocolInvoker(obj, entryPoint).InvokeProtocol0
162             End If
163
164             If parameters.Length = 1 Then
165                 If Not parameters.First.ParameterType.Equals(GetType(Long)) Then
166                     Return Nothing
167                 End If
168
169                 Return AddressOf New __protocolInvoker(obj, entryPoint).InvokeProtocol1
170             End If
171
172             If parameters.Length = 2 Then
173                 If (Not parameters.First.ParameterType.Equals(GetType(Long)) OrElse
174                 Not parameters.Last.ParameterType.Equals(GetType(RequestStream))) Then
175                     Return Nothing
176                 End If
177
178                 Return AddressOf New __protocolInvoker(obj, entryPoint).InvokeProtocol2
179             End If
180
181             If parameters.Length = 3 Then
182                 If (Not parameters.First.ParameterType.Equals(GetType(Long)) OrElse
183                 Not parameters(1).ParameterType.Equals(GetType(RequestStream)) OrElse
184                 Not parameters.Last.ParameterType.Equals(GetType(System.Net.IPEndPoint))) Then
185                     Return Nothing
186                 End If
187
188                 Return AddressOf New __protocolInvoker(obj, entryPoint).InvokeProtocol3
189             End If
190
191             Return Nothing
192         End Function
193     End Class
194 End Namespace