mirror of
				https://github.com/esiur/esiur-dart.git
				synced 2025-10-31 07:41:34 +00:00 
			
		
		
		
	1.4.5
This commit is contained in:
		| @@ -22,6 +22,8 @@ SOFTWARE. | ||||
|  | ||||
| */ | ||||
|  | ||||
| import '../Sockets/WSocket.dart'; | ||||
|  | ||||
| import '../../Resource/Template/TemplateDescriber.dart'; | ||||
| import '../../Resource/Template/TemplateType.dart'; | ||||
| import '../../Security/Authority/AuthenticationMethod.dart'; | ||||
| @@ -161,7 +163,7 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|   /// Send data to the other end as parameters | ||||
|   /// </summary> | ||||
|   /// <param name="values">Values will be converted to bytes then sent.</param> | ||||
|   SendList sendParams([AsyncReply<List<dynamic>>? reply = null]) { | ||||
|   SendList sendParams([AsyncReply<List<dynamic>?>? reply = null]) { | ||||
|     return new SendList(this, reply); | ||||
|   } | ||||
|  | ||||
| @@ -188,6 +190,11 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|  | ||||
|       var domain = instance?.attributes["domain"] ?? address; | ||||
|  | ||||
|       var ws = instance?.attributes.containsKey("ws") == true || | ||||
|           instance?.attributes.containsKey("wss") == true; | ||||
|       var secure = instance?.attributes.containsKey("secure") == true || | ||||
|           instance?.attributes.containsKey("wss") == true; | ||||
|  | ||||
|       if (instance?.attributes.containsKey("username") == true && | ||||
|           instance?.attributes.containsKey("password") == true) { | ||||
|         var username = instance?.attributes["username"] as String; | ||||
| @@ -200,7 +207,9 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|             hostname: address, | ||||
|             port: port, | ||||
|             passwordOrToken: password, | ||||
|             username: username); | ||||
|             username: username, | ||||
|             useWebsocket: ws, | ||||
|             secureWebSocket: secure); | ||||
|       } else if (instance?.attributes.containsKey("token") == true) { | ||||
|         var token = DC.stringToBytes(instance?.attributes["token"] ?? ""); | ||||
|         var tokenIndex = instance?.attributes["tokenIndex"] ?? 0; | ||||
| @@ -210,13 +219,17 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|             hostname: address, | ||||
|             port: port, | ||||
|             passwordOrToken: token, | ||||
|             tokenIndex: tokenIndex); | ||||
|             tokenIndex: tokenIndex, | ||||
|             useWebsocket: ws, | ||||
|             secureWebSocket: secure); | ||||
|       } else { | ||||
|         return connect( | ||||
|             method: AuthenticationMethod.None, | ||||
|             hostname: address, | ||||
|             port: port, | ||||
|             domain: domain); | ||||
|             domain: domain, | ||||
|             useWebsocket: ws, | ||||
|             secureWebSocket: secure); | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @@ -231,7 +244,9 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|       String? username, | ||||
|       int? tokenIndex, | ||||
|       DC? passwordOrToken, | ||||
|       String? domain}) { | ||||
|       String? domain, | ||||
|       bool useWebsocket = false, | ||||
|       bool secureWebSocket = false}) { | ||||
|     if (_openReply != null) | ||||
|       throw AsyncException(ErrorType.Exception, 0, "Connection in progress"); | ||||
|  | ||||
| @@ -251,19 +266,26 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|     if (_session == null) | ||||
|       throw AsyncException(ErrorType.Exception, 0, "Session not initialized"); | ||||
|  | ||||
|     if (socket == null) socket = new TCPSocket(); | ||||
|     if (socket == null) { | ||||
|       if (useWebsocket) { | ||||
|         socket = new WSocket()..secure = secureWebSocket; | ||||
|       } else | ||||
|         socket = new TCPSocket(); | ||||
|     } | ||||
|  | ||||
|     _port = port ?? _port; | ||||
|     _hostname = hostname ?? _hostname; | ||||
|  | ||||
|     if (_hostname == null) throw Exception("Host not specified."); | ||||
|  | ||||
|     socket.connect(_hostname as String, _port).then<dynamic>((x) { | ||||
|       assign(socket as ISocket); | ||||
|     }).error((x) { | ||||
|       _openReply?.triggerError(x); | ||||
|       _openReply = null; | ||||
|     }); | ||||
|     if (socket != null) { | ||||
|       socket.connect(_hostname as String, _port).then<dynamic>((x) { | ||||
|         assign(socket as ISocket); | ||||
|       }).error((x) { | ||||
|         _openReply?.triggerError(x); | ||||
|         _openReply = null; | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     return _openReply as AsyncReply<bool>; | ||||
|   } | ||||
| @@ -961,7 +983,7 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|   /// <param name="args">Arguments to send.</param> | ||||
|   /// <returns></returns> | ||||
|   SendList sendRequest(int action) { | ||||
|     var reply = new AsyncReply<List<dynamic>>(); | ||||
|     var reply = new AsyncReply<List<dynamic>?>(); | ||||
|     var c = _callbackCounter++; // avoid thread racing | ||||
|     _requests.add(c, reply); | ||||
|  | ||||
| @@ -2248,10 +2270,14 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|  | ||||
|     (sendRequest(IIPPacketAction.TemplateFromClassId)..addGuid(classId)).done() | ||||
|       ..then((rt) { | ||||
|         _templateRequests.remove(classId); | ||||
|         _templates[(rt[0] as TypeTemplate).classId] = rt[0] as TypeTemplate; | ||||
|         Warehouse.putTemplate(rt[0] as TypeTemplate); | ||||
|         reply.trigger(rt[0]); | ||||
|         if (rt != null) { | ||||
|           _templateRequests.remove(classId); | ||||
|           _templates[(rt[0] as TypeTemplate).classId] = rt[0] as TypeTemplate; | ||||
|           Warehouse.putTemplate(rt[0] as TypeTemplate); | ||||
|           reply.trigger(rt[0]); | ||||
|         } else { | ||||
|           reply.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }) | ||||
|       ..error((ex) { | ||||
|         reply.triggerError(ex); | ||||
| @@ -2301,24 +2327,28 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|           ..addUint16(l.length) | ||||
|           ..addDC(l)) | ||||
|         .done() | ||||
|           ..then((rt) { | ||||
|             List<TypeTemplate> templates = []; | ||||
|             // parse templates | ||||
|       ..then((rt) { | ||||
|         List<TypeTemplate> templates = []; | ||||
|         // parse templates | ||||
|  | ||||
|             DC data = rt[0]; | ||||
|             //var offset = 0; | ||||
|             for (int offset = 0; offset < data.length;) { | ||||
|               var cs = data.getUint32(offset); | ||||
|               offset += 4; | ||||
|               templates.add(TypeTemplate.parse(data, offset, cs)); | ||||
|               offset += cs; | ||||
|             } | ||||
|         if (rt != null) { | ||||
|           DC data = rt[0]; | ||||
|           //var offset = 0; | ||||
|           for (int offset = 0; offset < data.length;) { | ||||
|             var cs = data.getUint32(offset); | ||||
|             offset += 4; | ||||
|             templates.add(TypeTemplate.parse(data, offset, cs)); | ||||
|             offset += cs; | ||||
|           } | ||||
|         } else { | ||||
|           reply.triggerError(Exception("Null response")); | ||||
|         } | ||||
|  | ||||
|             reply.trigger(templates); | ||||
|           }) | ||||
|           ..error((ex) { | ||||
|             reply.triggerError(ex); | ||||
|           }); | ||||
|         reply.trigger(templates); | ||||
|       }) | ||||
|       ..error((ex) { | ||||
|         reply.triggerError(ex); | ||||
|       }); | ||||
|  | ||||
|     return reply; | ||||
|   } | ||||
| @@ -2347,55 +2377,59 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|  | ||||
|     (sendRequest(IIPPacketAction.AttachResource)..addUint32(id)).done() | ||||
|       ..then((rt) { | ||||
|         // @TODO: Generator code | ||||
|         DistributedResource dr; | ||||
|         if (rt != null) { | ||||
|           // @TODO: Generator code | ||||
|           DistributedResource dr; | ||||
|  | ||||
|         if (resource == null) { | ||||
|           var template = | ||||
|               Warehouse.getTemplateByClassId(rt[0], TemplateType.Wrapper); | ||||
|           if (template?.definedType != null) { | ||||
|             dr = Warehouse.createInstance(template?.definedType as Type); | ||||
|             dr.internal_init(this, id, rt[1], rt[2]); | ||||
|           } else { | ||||
|             dr = new DistributedResource(); | ||||
|             dr.internal_init(this, id, rt[1], rt[2]); | ||||
|           } | ||||
|         } else | ||||
|           dr = resource; | ||||
|  | ||||
|         //var dr = resource ?? new DistributedResource(this, id, rt[1], rt[2]); | ||||
|  | ||||
|         getTemplate(rt[0] as Guid) | ||||
|           ..then((tmp) { | ||||
|             //print("New template "); | ||||
|  | ||||
|             var d = rt[3] as DC; | ||||
|  | ||||
|             // ClassId, ResourceAge, ResourceLink, Content | ||||
|             if (resource == null) { | ||||
|               Warehouse.put(id.toString(), dr, this, null, tmp) | ||||
|                 ..then((ok) { | ||||
|                   Codec.parsePropertyValueArray(d, 0, d.length, this) | ||||
|                       .then((ar) { | ||||
|                     //print("attached"); | ||||
|                     dr.internal_attach(ar); | ||||
|                     _resourceRequests.remove(id); | ||||
|                     reply.trigger(dr); | ||||
|                   }); | ||||
|                 }) | ||||
|                 ..error((ex) => reply.triggerError(ex)); | ||||
|           if (resource == null) { | ||||
|             var template = | ||||
|                 Warehouse.getTemplateByClassId(rt[0], TemplateType.Wrapper); | ||||
|             if (template?.definedType != null) { | ||||
|               dr = Warehouse.createInstance(template?.definedType as Type); | ||||
|               dr.internal_init(this, id, rt[1], rt[2]); | ||||
|             } else { | ||||
|               Codec.parsePropertyValueArray(d, 0, d.length, this).then((ar) { | ||||
|                 //print("attached"); | ||||
|                 if (ar != null) dr.internal_attach(ar); | ||||
|                 _resourceRequests.remove(id); | ||||
|                 reply.trigger(dr); | ||||
|               }); | ||||
|               dr = new DistributedResource(); | ||||
|               dr.internal_init(this, id, rt[1], rt[2]); | ||||
|             } | ||||
|           }) | ||||
|           ..error((ex) { | ||||
|             reply.triggerError(ex); | ||||
|           }); | ||||
|           } else | ||||
|             dr = resource; | ||||
|  | ||||
|           //var dr = resource ?? new DistributedResource(this, id, rt[1], rt[2]); | ||||
|  | ||||
|           getTemplate(rt[0] as Guid) | ||||
|             ..then((tmp) { | ||||
|               //print("New template "); | ||||
|  | ||||
|               var d = rt[3] as DC; | ||||
|  | ||||
|               // ClassId, ResourceAge, ResourceLink, Content | ||||
|               if (resource == null) { | ||||
|                 Warehouse.put(id.toString(), dr, this, null, tmp) | ||||
|                   ..then((ok) { | ||||
|                     Codec.parsePropertyValueArray(d, 0, d.length, this) | ||||
|                         .then((ar) { | ||||
|                       //print("attached"); | ||||
|                       dr.internal_attach(ar); | ||||
|                       _resourceRequests.remove(id); | ||||
|                       reply.trigger(dr); | ||||
|                     }); | ||||
|                   }) | ||||
|                   ..error((ex) => reply.triggerError(ex)); | ||||
|               } else { | ||||
|                 Codec.parsePropertyValueArray(d, 0, d.length, this).then((ar) { | ||||
|                   //print("attached"); | ||||
|                   if (ar != null) dr.internal_attach(ar); | ||||
|                   _resourceRequests.remove(id); | ||||
|                   reply.trigger(dr); | ||||
|                 }); | ||||
|               } | ||||
|             }) | ||||
|             ..error((ex) { | ||||
|               reply.triggerError(ex); | ||||
|             }); | ||||
|         } else { | ||||
|           reply.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }) | ||||
|       ..error((ex) { | ||||
|         reply.triggerError(ex); | ||||
| @@ -2410,10 +2444,14 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|     sendRequest(IIPPacketAction.ResourceChildren) | ||||
|       ..addUint32(resource.instance?.id as int) | ||||
|       ..done().then<dynamic>((ar) { | ||||
|         var d = ar[0] as DC; | ||||
|         Codec.parseResourceArray(d, 0, d.length, this).then((resources) { | ||||
|           rt.trigger(resources); | ||||
|         }).error((ex) => rt.triggerError(ex)); | ||||
|         if (ar != null) { | ||||
|           var d = ar[0] as DC; | ||||
|           Codec.parseResourceArray(d, 0, d.length, this).then((resources) { | ||||
|             rt.trigger(resources); | ||||
|           }).error((ex) => rt.triggerError(ex)); | ||||
|         } else { | ||||
|           rt.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|     return rt; | ||||
| @@ -2425,11 +2463,15 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|     sendRequest(IIPPacketAction.ResourceParents) | ||||
|       ..addUint32((resource.instance as Instance).id) | ||||
|       ..done().then<dynamic>((ar) { | ||||
|         var d = ar[0] as DC; | ||||
|         Codec.parseResourceArray(d, 0, d.length, this) | ||||
|             .then<dynamic>((resources) { | ||||
|           rt.trigger(resources); | ||||
|         }).error((ex) => rt.triggerError(ex)); | ||||
|         if (ar != null) { | ||||
|           var d = ar[0] as DC; | ||||
|           Codec.parseResourceArray(d, 0, d.length, this) | ||||
|               .then<dynamic>((resources) { | ||||
|             rt.trigger(resources); | ||||
|           }).error((ex) => rt.triggerError(ex)); | ||||
|         } else { | ||||
|           rt.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|     return rt; | ||||
| @@ -2443,8 +2485,8 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|       (sendRequest(IIPPacketAction.ClearAllAttributes) | ||||
|             ..addUint32(resource.instance?.id as int)) | ||||
|           .done() | ||||
|             ..then((ar) => rt.trigger(true)) | ||||
|             ..error((ex) => rt.triggerError(ex)); | ||||
|         ..then((ar) => rt.trigger(true)) | ||||
|         ..error((ex) => rt.triggerError(ex)); | ||||
|     else { | ||||
|       var attrs = DC.stringArrayToBytes(attributes); | ||||
|       (sendRequest(IIPPacketAction.ClearAttributes) | ||||
| @@ -2452,8 +2494,8 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|             ..addInt32(attrs.length) | ||||
|             ..addDC(attrs)) | ||||
|           .done() | ||||
|             ..then<dynamic>((ar) => rt.trigger(true)) | ||||
|             ..error((ex) => rt.triggerError(ex)); | ||||
|         ..then<dynamic>((ar) => rt.trigger(true)) | ||||
|         ..error((ex) => rt.triggerError(ex)); | ||||
|     } | ||||
|  | ||||
|     return rt; | ||||
| @@ -2483,15 +2525,19 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|       (sendRequest(IIPPacketAction.GetAllAttributes) | ||||
|             ..addUint32(resource.instance?.id as int)) | ||||
|           .done() | ||||
|             ..then((ar) { | ||||
|               var d = ar[0] as DC; | ||||
|               Codec.parseStructure(d, 0, d.length, this) | ||||
|                 ..then((st) { | ||||
|                   resource.instance?.setAttributes(st); | ||||
|                   rt.trigger(st); | ||||
|                 }) | ||||
|                 ..error((ex) => rt.triggerError(ex)); | ||||
|             }); | ||||
|         ..then((ar) { | ||||
|           if (ar != null) { | ||||
|             var d = ar[0] as DC; | ||||
|             Codec.parseStructure(d, 0, d.length, this) | ||||
|               ..then((st) { | ||||
|                 resource.instance?.setAttributes(st); | ||||
|                 rt.trigger(st); | ||||
|               }) | ||||
|               ..error((ex) => rt.triggerError(ex)); | ||||
|           } else { | ||||
|             rt.triggerError(Exception("Null response")); | ||||
|           } | ||||
|         }); | ||||
|     } else { | ||||
|       var attrs = DC.stringArrayToBytes(attributes); | ||||
|       (sendRequest(IIPPacketAction.GetAttributes) | ||||
| @@ -2499,16 +2545,20 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|             ..addInt32(attrs.length) | ||||
|             ..addDC(attrs)) | ||||
|           .done() | ||||
|             ..then((ar) { | ||||
|               var d = ar[0] as DC; | ||||
|               Codec.parseStructure(d, 0, d.length, this) | ||||
|                 ..then((st) { | ||||
|                   resource.instance?.setAttributes(st); | ||||
|         ..then((ar) { | ||||
|           if (ar != null) { | ||||
|             var d = ar[0] as DC; | ||||
|             Codec.parseStructure(d, 0, d.length, this) | ||||
|               ..then((st) { | ||||
|                 resource.instance?.setAttributes(st); | ||||
|  | ||||
|                   rt.trigger(st); | ||||
|                 }) | ||||
|                 ..error((ex) => rt.triggerError(ex)); | ||||
|             }); | ||||
|                 rt.trigger(st); | ||||
|               }) | ||||
|               ..error((ex) => rt.triggerError(ex)); | ||||
|           } else { | ||||
|             rt.triggerError(Exception("Null response")); | ||||
|           } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     return rt; | ||||
| @@ -2538,10 +2588,14 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|         ..addDateTime(fromDate) | ||||
|         ..addDateTime(toDate) | ||||
|         ..done().then<dynamic>((rt) { | ||||
|           var content = rt[0] as DC; | ||||
|           if (rt != null) { | ||||
|             var content = rt[0] as DC; | ||||
|  | ||||
|           Codec.parseHistory(content, 0, content.length, resource, this) | ||||
|               .then((history) => reply.trigger(history)); | ||||
|             Codec.parseHistory(content, 0, content.length, resource, this) | ||||
|                 .then((history) => reply.trigger(history)); | ||||
|           } else { | ||||
|             reply.triggerError(Exception("Null response")); | ||||
|           } | ||||
|         }).error((ex) => reply.triggerError(ex)); | ||||
|  | ||||
|       return reply; | ||||
| @@ -2563,10 +2617,14 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|       ..addUint16(str.length) | ||||
|       ..addDC(str) | ||||
|       ..done().then<dynamic>((args) { | ||||
|         var content = args[0] as DC; | ||||
|         if (args != null) { | ||||
|           var content = args[0] as DC; | ||||
|  | ||||
|         Codec.parseResourceArray(content, 0, content.length, this) | ||||
|             .then((resources) => reply.trigger(resources)); | ||||
|           Codec.parseResourceArray(content, 0, content.length, this) | ||||
|               .then((resources) => reply.trigger(resources)); | ||||
|         } else { | ||||
|           reply.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }).error((ex) => reply.triggerError(ex)); | ||||
|  | ||||
|     return reply; | ||||
| @@ -2602,11 +2660,15 @@ class DistributedConnection extends NetworkConnection with IStore { | ||||
|  | ||||
|     (sendRequest(IIPPacketAction.CreateResource)..addDC(pkt.toDC())).done() | ||||
|       ..then((args) { | ||||
|         var rid = args[0]; | ||||
|         if (args != null) { | ||||
|           var rid = args[0]; | ||||
|  | ||||
|         fetch(rid).then((r) { | ||||
|           reply.trigger(r); | ||||
|         }); | ||||
|           fetch(rid).then((r) { | ||||
|             reply.trigger(r); | ||||
|           }); | ||||
|         } else { | ||||
|           reply.triggerError(Exception("Null response")); | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|     return reply; | ||||
|   | ||||
| @@ -22,6 +22,7 @@ SOFTWARE. | ||||
|  | ||||
| */ | ||||
|  | ||||
| import 'dart:async'; | ||||
|  | ||||
| import '../../Resource/Instance.dart'; | ||||
|  | ||||
| @@ -371,12 +372,12 @@ class DistributedResource extends IResource { | ||||
|           ..addUint8(index) | ||||
|           ..addDC(parameters)) | ||||
|         .done() | ||||
|           ..then((res) { | ||||
|             // not really needed, server will always send property modified, | ||||
|             // this only happens if the programmer forgot to emit in property setter | ||||
|             _properties[index] = value; | ||||
|             reply.trigger(null); | ||||
|           }); | ||||
|       ..then((res) { | ||||
|         // not really needed, server will always send property modified, | ||||
|         // this only happens if the programmer forgot to emit in property setter | ||||
|         _properties[index] = value; | ||||
|         reply.trigger(null); | ||||
|       }); | ||||
|  | ||||
|     return reply; | ||||
|   } | ||||
|   | ||||
| @@ -4,12 +4,12 @@ import 'NetworkConnection.dart'; | ||||
|  | ||||
| class SendList extends BinaryList { | ||||
|   NetworkConnection connection; | ||||
|   AsyncReply<List<dynamic>>? reply; | ||||
|   AsyncReply<List<dynamic>?>? reply; | ||||
|  | ||||
|   SendList(this.connection, this.reply) {} | ||||
|  | ||||
|   @override | ||||
|   AsyncReply<List<dynamic>> done() { | ||||
|   AsyncReply<List<dynamic>?> done() { | ||||
|     connection.send(super.toDC()); | ||||
|  | ||||
|     return reply ?? AsyncReply.ready([]); | ||||
|   | ||||
							
								
								
									
										164
									
								
								lib/src/Net/Sockets/WSocket.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								lib/src/Net/Sockets/WSocket.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| /* | ||||
|   | ||||
| Copyright (c) 2019 Ahmed Kh. Zamil | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | ||||
| */ | ||||
|  | ||||
| import 'dart:io'; | ||||
|  | ||||
| //import 'package:web_socket_channel/io.dart' as WS; | ||||
| import 'package:web_socket_channel/io.dart'; | ||||
|  | ||||
| import '../../Core/ErrorType.dart'; | ||||
| import '../../Core/ExceptionCode.dart'; | ||||
|  | ||||
| import '../../Core/AsyncException.dart'; | ||||
|  | ||||
| import 'ISocket.dart'; | ||||
| import '../../Data/DC.dart'; | ||||
| import '../NetworkBuffer.dart'; | ||||
| import 'SocketState.dart'; | ||||
| import 'IPEndPoint.dart'; | ||||
| import '../../Core/AsyncReply.dart'; | ||||
|  | ||||
| class WSocket extends ISocket { | ||||
|   WebSocket? _sock; | ||||
|   IOWebSocketChannel? _channel; | ||||
|  | ||||
|   NetworkBuffer receiveNetworkBuffer = new NetworkBuffer(); | ||||
|  | ||||
|   bool began = false; | ||||
|  | ||||
|   bool secure = false; | ||||
|  | ||||
|   SocketState _state = SocketState.Initial; | ||||
|  | ||||
|   IPEndPoint? _localEP, _remoteEP; | ||||
|  | ||||
|   bool begin() { | ||||
|     if (began) return false; | ||||
|  | ||||
|     began = true; | ||||
|  | ||||
|     if (_sock != null) { | ||||
|       var s = _sock as Socket; | ||||
|       _localEP = IPEndPoint(s.address.rawAddress, s.port); | ||||
|       _remoteEP = IPEndPoint(s.remoteAddress.rawAddress, s.remotePort); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   void dataHandler(List<int> data) { | ||||
|     try { | ||||
|       if (_state == SocketState.Closed || _state == SocketState.Terminated) | ||||
|         return; | ||||
|  | ||||
|       var dc = new DC.fromList(data); | ||||
|       receiveNetworkBuffer.write(dc, 0, dc.length); | ||||
|       receiver?.networkReceive(this, receiveNetworkBuffer); | ||||
|     } catch (ex) { | ||||
|       if (_state != SocketState.Closed) // && !sock.connected) | ||||
|       { | ||||
|         _state = SocketState.Terminated; | ||||
|         close(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void errorHandler(error, StackTrace trace) { | ||||
|     print(error); | ||||
|   } | ||||
|  | ||||
|   void doneHandler() { | ||||
|     close(); | ||||
|     //_sock?.destroy(); | ||||
|   } | ||||
|  | ||||
|   AsyncReply<bool> connect(String hostname, int port) { | ||||
|     var rt = new AsyncReply<bool>(); | ||||
|  | ||||
|     try { | ||||
|       _state = SocketState.Connecting; | ||||
|  | ||||
|       WebSocket.connect("${secure ? 'wss' : 'ws'}://${hostname}:${port}'") | ||||
|           .then((s) { | ||||
|         _sock = s; | ||||
|         _state = SocketState.Established; | ||||
|         _channel = IOWebSocketChannel(s); | ||||
|         begin(); | ||||
|         receiver?.networkConnect(this); | ||||
|         rt.trigger(true); | ||||
|       }).catchError((ex) { | ||||
|         close(); | ||||
|         rt.triggerError(AsyncException(ErrorType.Management, | ||||
|             ExceptionCode.HostNotReachable.index, ex.toString())); | ||||
|       }); | ||||
|     } catch (ex) { | ||||
|       rt.triggerError(AsyncException(ErrorType.Management, | ||||
|           ExceptionCode.HostNotReachable.index, ex.toString())); | ||||
|     } | ||||
|  | ||||
|     return rt; | ||||
|   } | ||||
|  | ||||
|   IPEndPoint? get localEndPoint => _localEP; | ||||
|   IPEndPoint? get remoteEndPoint => _remoteEP; | ||||
|  | ||||
|   SocketState get state => _state; | ||||
|  | ||||
|   TCPSocket() { | ||||
|     // default constructor | ||||
|   } | ||||
|  | ||||
|   void close() { | ||||
|     if (state != SocketState.Closed && state != SocketState.Terminated) | ||||
|       _state = SocketState.Closed; | ||||
|  | ||||
|     _sock?.close(); | ||||
|  | ||||
|     receiver?.networkClose(this); | ||||
|  | ||||
|     //emitArgs("close", []); | ||||
|   } | ||||
|  | ||||
|   void send(DC message, [int? offset, int? size]) { | ||||
|     if (state == SocketState.Established) { | ||||
|       if (offset != null && size == null) { | ||||
|         _channel?.sink | ||||
|             .add(message.clip(offset, message.length - offset).toList()); | ||||
|       } else if (offset != null && size != null) { | ||||
|         _channel?.sink.add(message.clip(offset, size).toList()); | ||||
|       } else { | ||||
|         _channel?.sink.add(message.toList()); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void destroy() { | ||||
|     close(); | ||||
|     emitArgs("destroy", [this]); | ||||
|   } | ||||
|  | ||||
|   AsyncReply<ISocket> accept() { | ||||
|     var reply = new AsyncReply<ISocket>(); | ||||
|     return reply; | ||||
|   } | ||||
| } | ||||
| @@ -1,192 +0,0 @@ | ||||
| /* | ||||
|   | ||||
| Copyright (c) 2019 Ahmed Kh. Zamil | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  | ||||
| import 'dart:io'; | ||||
| import 'ISocket.dart'; | ||||
| import '../../Data/DC.dart'; | ||||
| import '../NetworkBuffer.dart'; | ||||
| import 'SocketState.dart'; | ||||
| import 'IPEndPoint.dart'; | ||||
| import '../../Core/AsyncReply.dart'; | ||||
|  | ||||
| import 'package:web_socket_channel/io.dart'; | ||||
| import 'package:web_socket_channel/web_socket_channel.dart'; | ||||
| import 'package:web_socket_channel/status.dart' as status; | ||||
|  | ||||
| class WSSocket extends ISocket | ||||
| { | ||||
|     WebSocketChannel sock; | ||||
|  | ||||
|     NetworkBuffer receiveNetworkBuffer = new NetworkBuffer(); | ||||
|  | ||||
|     bool began = false; | ||||
|  | ||||
|     SocketState _state = SocketState.Initial; | ||||
|  | ||||
|  | ||||
|     IPEndPoint _localEP, _remoteEP; | ||||
|  | ||||
|     bool begin() | ||||
|     { | ||||
|         if (began) | ||||
|             return false; | ||||
|  | ||||
|         began = true; | ||||
|  | ||||
|         _localEP = IPEndPoint(sock. address.rawAddress, sock.port); | ||||
|         _remoteEP = IPEndPoint(sock.remoteAddress.rawAddress, sock.remotePort); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void dataHandler(List<int> data){ | ||||
|       //print(new String.fromCharCodes(data).trim()); | ||||
|  | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             if (_state == SocketState.Closed || _state == SocketState.Terminated) | ||||
|                 return; | ||||
|  | ||||
|  | ||||
|             var dc = new DC.fromList(data); | ||||
|             receiveNetworkBuffer.write(dc, 0, dc.length); | ||||
|             emitArgs("receive", [receiveNetworkBuffer]); | ||||
|  | ||||
|         } | ||||
|         catch (ex) | ||||
|         { | ||||
|             if (_state != SocketState.Closed)// && !sock.connected) | ||||
|             { | ||||
|                 _state = SocketState.Terminated; | ||||
|                 close(); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     void errorHandler(error, StackTrace trace){ | ||||
|       print(error); | ||||
|     } | ||||
|  | ||||
|     void doneHandler(){ | ||||
|       sock.destroy(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     AsyncReply<bool> connect(String hostname, int port) | ||||
|     { | ||||
|       var rt = new AsyncReply<bool>(); | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             _state = SocketState.Connecting; | ||||
|  | ||||
|             WebSocket() | ||||
|             prefix0.WebSocket(url)  | ||||
|             IOWebSocketChannel. | ||||
|             Socket.connect(hostname, port).then((s){ | ||||
|                 sock = s; | ||||
|                 s.listen(dataHandler,  | ||||
|                     onError: errorHandler,  | ||||
|                     onDone: doneHandler,  | ||||
|                     cancelOnError: false); | ||||
|                 _state = SocketState.Established; | ||||
|                 emitArgs("connect", []); | ||||
|                 begin(); | ||||
|                 rt.trigger(true); | ||||
|  | ||||
|             }).catchError((ex){ | ||||
|               close(); | ||||
|               rt.triggerError(ex); | ||||
|             }); | ||||
|  | ||||
|              | ||||
|         } | ||||
|         catch(ex) | ||||
|         { | ||||
|             rt.triggerError(ex); | ||||
|         } | ||||
|  | ||||
|         return rt; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     IPEndPoint get localEndPoint => _localEP; | ||||
|     IPEndPoint get remoteEndPoint => _remoteEP; | ||||
|  | ||||
|     | ||||
|     SocketState get state => _state; | ||||
|      | ||||
|  | ||||
|     TCPSocket.fromSocket(Socket socket) | ||||
|     { | ||||
|         sock = socket; | ||||
|         //if (socket.) | ||||
|           //  _state = SocketState.Established; | ||||
|     } | ||||
|  | ||||
|     TCPSocket() | ||||
|     { | ||||
|       // default constructor | ||||
|     } | ||||
|  | ||||
|     void close() | ||||
|     { | ||||
|         if (state != SocketState.Closed && state != SocketState.Terminated) | ||||
|             _state = SocketState.Closed; | ||||
|  | ||||
|         sock?.close(); | ||||
|  | ||||
|         emitArgs("close", []); | ||||
|     } | ||||
|  | ||||
|      | ||||
|     void send(DC message, [int offset, int size]) | ||||
|     { | ||||
|         if (state == SocketState.Established) | ||||
|           sock.add(message.toList()); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     void destroy() | ||||
|     { | ||||
|         close(); | ||||
|         emitArgs("destroy", [this]); | ||||
|     } | ||||
|  | ||||
|     AsyncReply<ISocket> accept() | ||||
|     { | ||||
|  | ||||
|  | ||||
|         var reply = new AsyncReply<ISocket>(); | ||||
|         return reply; | ||||
|     } | ||||
| } | ||||
| */ | ||||
		Reference in New Issue
	
	Block a user