mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-05-06 04:02:57 +00:00
1.4.5
This commit is contained in:
parent
614c6853e3
commit
eed16df29a
1
.pubignore
Normal file
1
.pubignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
test/
|
@ -1,3 +1,9 @@
|
|||||||
|
## [1.4.3] - Hotfix
|
||||||
|
Bugfix
|
||||||
|
|
||||||
|
## [1.4.2] - Release
|
||||||
|
Added get-template command
|
||||||
|
|
||||||
## [1.2.3] - Release
|
## [1.2.3] - Release
|
||||||
Improved property updating
|
Improved property updating
|
||||||
|
|
||||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2021 Esiur Foundation, Ahmed Kh. Zamil
|
Copyright (c) 2019-2022 Esiur Foundation, Ahmed Kh. Zamil
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -1,47 +1,47 @@
|
|||||||
import 'package:source_gen/source_gen.dart';
|
// import 'package:source_gen/source_gen.dart';
|
||||||
import 'package:build/build.dart';
|
// import 'package:build/build.dart';
|
||||||
import 'package:yaml/yaml.dart';
|
// import 'package:yaml/yaml.dart';
|
||||||
|
|
||||||
//Builder iipService(BuilderOptions options) {
|
// //Builder iipService(BuilderOptions options) {
|
||||||
//return LibraryBuilder(TemplateBuilder(), generatedExtension: '.info.dart');
|
// //return LibraryBuilder(TemplateBuilder(), generatedExtension: '.info.dart');
|
||||||
//}
|
// //}
|
||||||
|
|
||||||
class TemplateBuilder implements Builder {
|
// class TemplateBuilder implements Builder {
|
||||||
//BuilderOptions options;
|
// //BuilderOptions options;
|
||||||
String _fileName;
|
// String _fileName;
|
||||||
TemplateBuilder([BuilderOptions? options]) : _fileName = _get_dest(options);
|
// TemplateBuilder([BuilderOptions? options]) : _fileName = _get_dest(options);
|
||||||
|
|
||||||
@override
|
|
||||||
Future build(BuildStep buildStep) async {
|
|
||||||
final id = AssetId(buildStep.inputId.package, _fileName);
|
|
||||||
|
|
||||||
// generate
|
|
||||||
var content = "Testing";
|
|
||||||
|
|
||||||
await buildStep.writeAsString(id, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _get_dest(BuilderOptions? options) {
|
|
||||||
const defaultDestination = 'lib/src/iip_template.dart';
|
|
||||||
if (options == null) return defaultDestination;
|
|
||||||
if (options.config == null) return defaultDestination;
|
|
||||||
return options.config['destination_file'] as String ?? defaultDestination;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, List<String>> get buildExtensions {
|
|
||||||
return {
|
|
||||||
'.iip.yaml': [".iip.dart"]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// class TemplateBuilder extends Generator {
|
|
||||||
// @override
|
// @override
|
||||||
// String generate(LibraryReader library, BuildStep buildStep) {
|
// Future build(BuildStep buildStep) async {
|
||||||
// return '''
|
// final id = AssetId(buildStep.inputId.package, _fileName);
|
||||||
// // Source library: ${library.element.source.uri}
|
|
||||||
// const Testinggggg = 3;
|
// // generate
|
||||||
// ''';
|
// var content = "Testing";
|
||||||
|
|
||||||
|
// await buildStep.writeAsString(id, content);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static String _get_dest(BuilderOptions? options) {
|
||||||
|
// const defaultDestination = 'lib/src/iip_template.dart';
|
||||||
|
// if (options == null) return defaultDestination;
|
||||||
|
// if (options.config == null) return defaultDestination;
|
||||||
|
// return options.config['destination_file'] as String ?? defaultDestination;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Map<String, List<String>> get buildExtensions {
|
||||||
|
// return {
|
||||||
|
// '.iip.yaml': [".iip.dart"]
|
||||||
|
// };
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// // class TemplateBuilder extends Generator {
|
||||||
|
// // @override
|
||||||
|
// // String generate(LibraryReader library, BuildStep buildStep) {
|
||||||
|
// // return '''
|
||||||
|
// // // Source library: ${library.element.source.uri}
|
||||||
|
// // const Testinggggg = 3;
|
||||||
|
// // ''';
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
@ -23,7 +23,14 @@ class AsyncBag<T> extends AsyncReply<List<T>> {
|
|||||||
if (_sealedBag) return;
|
if (_sealedBag) return;
|
||||||
_sealedBag = true;
|
_sealedBag = true;
|
||||||
|
|
||||||
if (_replies.length == 0) trigger(<T>[]);
|
if (_replies.length == 0) {
|
||||||
|
if (arrayType != null) {
|
||||||
|
var ar = Warehouse.createArray(arrayType as Type);
|
||||||
|
trigger(ar as List<T>);
|
||||||
|
} else {
|
||||||
|
trigger(<T>[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var results = List<T?>.filled(_replies.length, null);
|
var results = List<T?>.filled(_replies.length, null);
|
||||||
|
|
||||||
@ -31,21 +38,23 @@ class AsyncBag<T> extends AsyncReply<List<T>> {
|
|||||||
var k = _replies[i];
|
var k = _replies[i];
|
||||||
var index = i;
|
var index = i;
|
||||||
|
|
||||||
k..then((r) {
|
k
|
||||||
results[index] = r;
|
..then((r) {
|
||||||
_count++;
|
results[index] = r;
|
||||||
if (_count == _replies.length) {
|
_count++;
|
||||||
if (arrayType != null) {
|
if (_count == _replies.length) {
|
||||||
var ar = Warehouse.createArray(arrayType as Type);
|
if (arrayType != null) {
|
||||||
results.forEach(ar.add);
|
var ar = Warehouse.createArray(arrayType as Type);
|
||||||
trigger(ar as List<T>);
|
results.forEach(ar.add);
|
||||||
} else {
|
trigger(ar as List<T>);
|
||||||
trigger(results.cast<T>());
|
} else {
|
||||||
|
trigger(results.cast<T>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})..error((ex) {
|
..error((ex) {
|
||||||
triggerError(ex);
|
triggerError(ex);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
class IEventHandler {
|
class IEventHandler {
|
||||||
|
final _propertyModifiedController = StreamController<String>();
|
||||||
|
|
||||||
Map<String, List<Function>> _events = {};
|
Map<String, List<Function>> _events = {};
|
||||||
|
|
||||||
register(String event) {
|
register(String event) {
|
||||||
@ -7,6 +11,12 @@ class IEventHandler {
|
|||||||
|
|
||||||
IEventHandler() {}
|
IEventHandler() {}
|
||||||
|
|
||||||
|
Stream get properyModified => _propertyModifiedController.stream;
|
||||||
|
|
||||||
|
emitProperty(String name) {
|
||||||
|
_propertyModifiedController.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
emitArgs(String event, List arguments) {
|
emitArgs(String event, List arguments) {
|
||||||
//event = event.toLowerCase();
|
//event = event.toLowerCase();
|
||||||
|
|
||||||
@ -21,13 +31,13 @@ class IEventHandler {
|
|||||||
|
|
||||||
on(String event, Function callback) {
|
on(String event, Function callback) {
|
||||||
event = event.toLowerCase();
|
event = event.toLowerCase();
|
||||||
if (_events.containsKey(event)) register(event);
|
if (!_events.containsKey(event)) register(event);
|
||||||
_events[event]?.add(callback);
|
_events[event]?.add(callback);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
off(event, callback) {
|
off(String event, callback) {
|
||||||
event = event.toString();
|
event = event.toLowerCase();
|
||||||
if (_events.containsKey(event)) {
|
if (_events.containsKey(event)) {
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
_events[event]?.remove(callback);
|
_events[event]?.remove(callback);
|
||||||
|
@ -170,9 +170,12 @@ class Codec {
|
|||||||
|
|
||||||
AsyncReply<IRecord?>? previous = null;
|
AsyncReply<IRecord?>? previous = null;
|
||||||
|
|
||||||
if (result == RecordComparisonResult.Null)
|
if (result == RecordComparisonResult.Empty) {
|
||||||
|
reply.seal();
|
||||||
|
return reply;
|
||||||
|
} else if (result == RecordComparisonResult.Null) {
|
||||||
previous = AsyncReply<IRecord?>.ready(null);
|
previous = AsyncReply<IRecord?>.ready(null);
|
||||||
else if (result == RecordComparisonResult.Record ||
|
} else if (result == RecordComparisonResult.Record ||
|
||||||
result == RecordComparisonResult.RecordSameType) {
|
result == RecordComparisonResult.RecordSameType) {
|
||||||
var cs = data.getUint32(offset);
|
var cs = data.getUint32(offset);
|
||||||
var recordLength = cs;
|
var recordLength = cs;
|
||||||
@ -203,8 +206,10 @@ class Codec {
|
|||||||
} else {
|
} else {
|
||||||
AsyncReply<IRecord?>? previous = null;
|
AsyncReply<IRecord?>? previous = null;
|
||||||
Guid? classId = null;
|
Guid? classId = null;
|
||||||
|
if (result == RecordComparisonResult.Empty) {
|
||||||
if (result == RecordComparisonResult.Null)
|
reply.seal();
|
||||||
|
return reply;
|
||||||
|
} else if (result == RecordComparisonResult.Null)
|
||||||
previous = new AsyncReply<IRecord?>.ready(null);
|
previous = new AsyncReply<IRecord?>.ready(null);
|
||||||
else if (result == RecordComparisonResult.Record) {
|
else if (result == RecordComparisonResult.Record) {
|
||||||
var cs = data.getUint32(offset);
|
var cs = data.getUint32(offset);
|
||||||
@ -392,11 +397,13 @@ class Codec {
|
|||||||
static DC composeRecordArray<T extends IRecord>(
|
static DC composeRecordArray<T extends IRecord>(
|
||||||
List<T>? records, DistributedConnection connection,
|
List<T>? records, DistributedConnection connection,
|
||||||
[bool prependLength = false]) {
|
[bool prependLength = false]) {
|
||||||
if (records == null || records.length == 0)
|
if (records == null) // || records.length == 0)
|
||||||
return prependLength ? new DC(4) : new DC(0);
|
return prependLength ? new DC(4) : new DC(0);
|
||||||
|
|
||||||
var rt = new BinaryList();
|
var rt = new BinaryList();
|
||||||
var comparsion = compareRecords(null, records[0]);
|
var comparsion = records.length == 0
|
||||||
|
? RecordComparisonResult.Empty
|
||||||
|
: compareRecords(null, records[0]);
|
||||||
|
|
||||||
//var type = records.getType().GetElementType();
|
//var type = records.getType().GetElementType();
|
||||||
var isTyped = T == IRecord; // != typeof(IRecord);
|
var isTyped = T == IRecord; // != typeof(IRecord);
|
||||||
@ -960,11 +967,14 @@ class Codec {
|
|||||||
static DC composeResourceArray<T extends IResource>(
|
static DC composeResourceArray<T extends IResource>(
|
||||||
List<T>? resources, DistributedConnection connection,
|
List<T>? resources, DistributedConnection connection,
|
||||||
[bool prependLength = false]) {
|
[bool prependLength = false]) {
|
||||||
if (resources == null || resources.length == 0)
|
if (resources == null) // || resources.length == 0)
|
||||||
return prependLength ? new DC(4) : new DC(0);
|
return prependLength ? new DC(4) : new DC(0);
|
||||||
|
|
||||||
var rt = new BinaryList();
|
var rt = new BinaryList();
|
||||||
var comparsion = compareResources(null, resources[0], connection);
|
//var comparsion = compareResources(null, resources[0], connection);
|
||||||
|
var comparsion = resources.length == 0
|
||||||
|
? ResourceComparisonResult.Empty
|
||||||
|
: compareResources(null, resources[0], connection);
|
||||||
|
|
||||||
if (T != IResource) {
|
if (T != IResource) {
|
||||||
// get template
|
// get template
|
||||||
@ -1048,7 +1058,10 @@ class Codec {
|
|||||||
|
|
||||||
AsyncReply<IResource?>? previous = null;
|
AsyncReply<IResource?>? previous = null;
|
||||||
|
|
||||||
if (result == ResourceComparisonResult.Null)
|
if (result == ResourceComparisonResult.Empty) {
|
||||||
|
reply.seal();
|
||||||
|
return reply;
|
||||||
|
} else if (result == ResourceComparisonResult.Null)
|
||||||
previous = new AsyncReply<IResource?>.ready(null);
|
previous = new AsyncReply<IResource?>.ready(null);
|
||||||
else if (result == ResourceComparisonResult.Local) {
|
else if (result == ResourceComparisonResult.Local) {
|
||||||
previous = Warehouse.getById(data.getUint32(offset));
|
previous = Warehouse.getById(data.getUint32(offset));
|
||||||
@ -1065,7 +1078,10 @@ class Codec {
|
|||||||
|
|
||||||
AsyncReply<IResource?>? current = null;
|
AsyncReply<IResource?>? current = null;
|
||||||
|
|
||||||
if (result == ResourceComparisonResult.Null) {
|
if (result == ResourceComparisonResult.Empty) {
|
||||||
|
reply.seal();
|
||||||
|
return reply;
|
||||||
|
} else if (result == ResourceComparisonResult.Null) {
|
||||||
current = new AsyncReply<IResource?>.ready(null);
|
current = new AsyncReply<IResource?>.ready(null);
|
||||||
} else if (result == ResourceComparisonResult.Same) {
|
} else if (result == ResourceComparisonResult.Same) {
|
||||||
current = previous;
|
current = previous;
|
||||||
|
@ -3,4 +3,6 @@ class RecordComparisonResult {
|
|||||||
static const Record = 1;
|
static const Record = 1;
|
||||||
static const RecordSameType = 2;
|
static const RecordSameType = 2;
|
||||||
static const Same = 3;
|
static const Same = 3;
|
||||||
|
static const Empty = 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
class ResourceComparisonResult
|
class ResourceComparisonResult {
|
||||||
{
|
static const Null = 0;
|
||||||
static const Null = 0;
|
static const Distributed = 1;
|
||||||
static const Distributed = 1;
|
static const Local = 2;
|
||||||
static const Local = 2;
|
static const Same = 3;
|
||||||
static const Same = 3;
|
static const Empty = 4;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ SOFTWARE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import '../Sockets/WSocket.dart';
|
||||||
|
|
||||||
import '../../Resource/Template/TemplateDescriber.dart';
|
import '../../Resource/Template/TemplateDescriber.dart';
|
||||||
import '../../Resource/Template/TemplateType.dart';
|
import '../../Resource/Template/TemplateType.dart';
|
||||||
import '../../Security/Authority/AuthenticationMethod.dart';
|
import '../../Security/Authority/AuthenticationMethod.dart';
|
||||||
@ -161,7 +163,7 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
/// Send data to the other end as parameters
|
/// Send data to the other end as parameters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="values">Values will be converted to bytes then sent.</param>
|
/// <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);
|
return new SendList(this, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,6 +190,11 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
|
|
||||||
var domain = instance?.attributes["domain"] ?? address;
|
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 &&
|
if (instance?.attributes.containsKey("username") == true &&
|
||||||
instance?.attributes.containsKey("password") == true) {
|
instance?.attributes.containsKey("password") == true) {
|
||||||
var username = instance?.attributes["username"] as String;
|
var username = instance?.attributes["username"] as String;
|
||||||
@ -200,7 +207,9 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
hostname: address,
|
hostname: address,
|
||||||
port: port,
|
port: port,
|
||||||
passwordOrToken: password,
|
passwordOrToken: password,
|
||||||
username: username);
|
username: username,
|
||||||
|
useWebsocket: ws,
|
||||||
|
secureWebSocket: secure);
|
||||||
} else if (instance?.attributes.containsKey("token") == true) {
|
} else if (instance?.attributes.containsKey("token") == true) {
|
||||||
var token = DC.stringToBytes(instance?.attributes["token"] ?? "");
|
var token = DC.stringToBytes(instance?.attributes["token"] ?? "");
|
||||||
var tokenIndex = instance?.attributes["tokenIndex"] ?? 0;
|
var tokenIndex = instance?.attributes["tokenIndex"] ?? 0;
|
||||||
@ -210,13 +219,17 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
hostname: address,
|
hostname: address,
|
||||||
port: port,
|
port: port,
|
||||||
passwordOrToken: token,
|
passwordOrToken: token,
|
||||||
tokenIndex: tokenIndex);
|
tokenIndex: tokenIndex,
|
||||||
|
useWebsocket: ws,
|
||||||
|
secureWebSocket: secure);
|
||||||
} else {
|
} else {
|
||||||
return connect(
|
return connect(
|
||||||
method: AuthenticationMethod.None,
|
method: AuthenticationMethod.None,
|
||||||
hostname: address,
|
hostname: address,
|
||||||
port: port,
|
port: port,
|
||||||
domain: domain);
|
domain: domain,
|
||||||
|
useWebsocket: ws,
|
||||||
|
secureWebSocket: secure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +244,9 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
String? username,
|
String? username,
|
||||||
int? tokenIndex,
|
int? tokenIndex,
|
||||||
DC? passwordOrToken,
|
DC? passwordOrToken,
|
||||||
String? domain}) {
|
String? domain,
|
||||||
|
bool useWebsocket = false,
|
||||||
|
bool secureWebSocket = false}) {
|
||||||
if (_openReply != null)
|
if (_openReply != null)
|
||||||
throw AsyncException(ErrorType.Exception, 0, "Connection in progress");
|
throw AsyncException(ErrorType.Exception, 0, "Connection in progress");
|
||||||
|
|
||||||
@ -251,19 +266,26 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
if (_session == null)
|
if (_session == null)
|
||||||
throw AsyncException(ErrorType.Exception, 0, "Session not initialized");
|
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;
|
_port = port ?? _port;
|
||||||
_hostname = hostname ?? _hostname;
|
_hostname = hostname ?? _hostname;
|
||||||
|
|
||||||
if (_hostname == null) throw Exception("Host not specified.");
|
if (_hostname == null) throw Exception("Host not specified.");
|
||||||
|
|
||||||
socket.connect(_hostname as String, _port).then<dynamic>((x) {
|
if (socket != null) {
|
||||||
assign(socket as ISocket);
|
socket.connect(_hostname as String, _port).then<dynamic>((x) {
|
||||||
}).error((x) {
|
assign(socket as ISocket);
|
||||||
_openReply?.triggerError(x);
|
}).error((x) {
|
||||||
_openReply = null;
|
_openReply?.triggerError(x);
|
||||||
});
|
_openReply = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return _openReply as AsyncReply<bool>;
|
return _openReply as AsyncReply<bool>;
|
||||||
}
|
}
|
||||||
@ -961,7 +983,7 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
/// <param name="args">Arguments to send.</param>
|
/// <param name="args">Arguments to send.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
SendList sendRequest(int action) {
|
SendList sendRequest(int action) {
|
||||||
var reply = new AsyncReply<List<dynamic>>();
|
var reply = new AsyncReply<List<dynamic>?>();
|
||||||
var c = _callbackCounter++; // avoid thread racing
|
var c = _callbackCounter++; // avoid thread racing
|
||||||
_requests.add(c, reply);
|
_requests.add(c, reply);
|
||||||
|
|
||||||
@ -2248,10 +2270,14 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
|
|
||||||
(sendRequest(IIPPacketAction.TemplateFromClassId)..addGuid(classId)).done()
|
(sendRequest(IIPPacketAction.TemplateFromClassId)..addGuid(classId)).done()
|
||||||
..then((rt) {
|
..then((rt) {
|
||||||
_templateRequests.remove(classId);
|
if (rt != null) {
|
||||||
_templates[(rt[0] as TypeTemplate).classId] = rt[0] as TypeTemplate;
|
_templateRequests.remove(classId);
|
||||||
Warehouse.putTemplate(rt[0] as TypeTemplate);
|
_templates[(rt[0] as TypeTemplate).classId] = rt[0] as TypeTemplate;
|
||||||
reply.trigger(rt[0]);
|
Warehouse.putTemplate(rt[0] as TypeTemplate);
|
||||||
|
reply.trigger(rt[0]);
|
||||||
|
} else {
|
||||||
|
reply.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
..error((ex) {
|
..error((ex) {
|
||||||
reply.triggerError(ex);
|
reply.triggerError(ex);
|
||||||
@ -2301,24 +2327,28 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
..addUint16(l.length)
|
..addUint16(l.length)
|
||||||
..addDC(l))
|
..addDC(l))
|
||||||
.done()
|
.done()
|
||||||
..then((rt) {
|
..then((rt) {
|
||||||
List<TypeTemplate> templates = [];
|
List<TypeTemplate> templates = [];
|
||||||
// parse templates
|
// parse templates
|
||||||
|
|
||||||
DC data = rt[0];
|
if (rt != null) {
|
||||||
//var offset = 0;
|
DC data = rt[0];
|
||||||
for (int offset = 0; offset < data.length;) {
|
//var offset = 0;
|
||||||
var cs = data.getUint32(offset);
|
for (int offset = 0; offset < data.length;) {
|
||||||
offset += 4;
|
var cs = data.getUint32(offset);
|
||||||
templates.add(TypeTemplate.parse(data, offset, cs));
|
offset += 4;
|
||||||
offset += cs;
|
templates.add(TypeTemplate.parse(data, offset, cs));
|
||||||
}
|
offset += cs;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reply.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
|
|
||||||
reply.trigger(templates);
|
reply.trigger(templates);
|
||||||
})
|
})
|
||||||
..error((ex) {
|
..error((ex) {
|
||||||
reply.triggerError(ex);
|
reply.triggerError(ex);
|
||||||
});
|
});
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
@ -2347,55 +2377,59 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
|
|
||||||
(sendRequest(IIPPacketAction.AttachResource)..addUint32(id)).done()
|
(sendRequest(IIPPacketAction.AttachResource)..addUint32(id)).done()
|
||||||
..then((rt) {
|
..then((rt) {
|
||||||
// @TODO: Generator code
|
if (rt != null) {
|
||||||
DistributedResource dr;
|
// @TODO: Generator code
|
||||||
|
DistributedResource dr;
|
||||||
|
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
var template =
|
var template =
|
||||||
Warehouse.getTemplateByClassId(rt[0], TemplateType.Wrapper);
|
Warehouse.getTemplateByClassId(rt[0], TemplateType.Wrapper);
|
||||||
if (template?.definedType != null) {
|
if (template?.definedType != null) {
|
||||||
dr = Warehouse.createInstance(template?.definedType as Type);
|
dr = Warehouse.createInstance(template?.definedType as Type);
|
||||||
dr.internal_init(this, id, rt[1], rt[2]);
|
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));
|
|
||||||
} else {
|
} else {
|
||||||
Codec.parsePropertyValueArray(d, 0, d.length, this).then((ar) {
|
dr = new DistributedResource();
|
||||||
//print("attached");
|
dr.internal_init(this, id, rt[1], rt[2]);
|
||||||
if (ar != null) dr.internal_attach(ar);
|
|
||||||
_resourceRequests.remove(id);
|
|
||||||
reply.trigger(dr);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
} else
|
||||||
..error((ex) {
|
dr = resource;
|
||||||
reply.triggerError(ex);
|
|
||||||
});
|
//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) {
|
..error((ex) {
|
||||||
reply.triggerError(ex);
|
reply.triggerError(ex);
|
||||||
@ -2410,10 +2444,14 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
sendRequest(IIPPacketAction.ResourceChildren)
|
sendRequest(IIPPacketAction.ResourceChildren)
|
||||||
..addUint32(resource.instance?.id as int)
|
..addUint32(resource.instance?.id as int)
|
||||||
..done().then<dynamic>((ar) {
|
..done().then<dynamic>((ar) {
|
||||||
var d = ar[0] as DC;
|
if (ar != null) {
|
||||||
Codec.parseResourceArray(d, 0, d.length, this).then((resources) {
|
var d = ar[0] as DC;
|
||||||
rt.trigger(resources);
|
Codec.parseResourceArray(d, 0, d.length, this).then((resources) {
|
||||||
}).error((ex) => rt.triggerError(ex));
|
rt.trigger(resources);
|
||||||
|
}).error((ex) => rt.triggerError(ex));
|
||||||
|
} else {
|
||||||
|
rt.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -2425,11 +2463,15 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
sendRequest(IIPPacketAction.ResourceParents)
|
sendRequest(IIPPacketAction.ResourceParents)
|
||||||
..addUint32((resource.instance as Instance).id)
|
..addUint32((resource.instance as Instance).id)
|
||||||
..done().then<dynamic>((ar) {
|
..done().then<dynamic>((ar) {
|
||||||
var d = ar[0] as DC;
|
if (ar != null) {
|
||||||
Codec.parseResourceArray(d, 0, d.length, this)
|
var d = ar[0] as DC;
|
||||||
.then<dynamic>((resources) {
|
Codec.parseResourceArray(d, 0, d.length, this)
|
||||||
rt.trigger(resources);
|
.then<dynamic>((resources) {
|
||||||
}).error((ex) => rt.triggerError(ex));
|
rt.trigger(resources);
|
||||||
|
}).error((ex) => rt.triggerError(ex));
|
||||||
|
} else {
|
||||||
|
rt.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -2443,8 +2485,8 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
(sendRequest(IIPPacketAction.ClearAllAttributes)
|
(sendRequest(IIPPacketAction.ClearAllAttributes)
|
||||||
..addUint32(resource.instance?.id as int))
|
..addUint32(resource.instance?.id as int))
|
||||||
.done()
|
.done()
|
||||||
..then((ar) => rt.trigger(true))
|
..then((ar) => rt.trigger(true))
|
||||||
..error((ex) => rt.triggerError(ex));
|
..error((ex) => rt.triggerError(ex));
|
||||||
else {
|
else {
|
||||||
var attrs = DC.stringArrayToBytes(attributes);
|
var attrs = DC.stringArrayToBytes(attributes);
|
||||||
(sendRequest(IIPPacketAction.ClearAttributes)
|
(sendRequest(IIPPacketAction.ClearAttributes)
|
||||||
@ -2452,8 +2494,8 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
..addInt32(attrs.length)
|
..addInt32(attrs.length)
|
||||||
..addDC(attrs))
|
..addDC(attrs))
|
||||||
.done()
|
.done()
|
||||||
..then<dynamic>((ar) => rt.trigger(true))
|
..then<dynamic>((ar) => rt.trigger(true))
|
||||||
..error((ex) => rt.triggerError(ex));
|
..error((ex) => rt.triggerError(ex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -2483,15 +2525,19 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
(sendRequest(IIPPacketAction.GetAllAttributes)
|
(sendRequest(IIPPacketAction.GetAllAttributes)
|
||||||
..addUint32(resource.instance?.id as int))
|
..addUint32(resource.instance?.id as int))
|
||||||
.done()
|
.done()
|
||||||
..then((ar) {
|
..then((ar) {
|
||||||
var d = ar[0] as DC;
|
if (ar != null) {
|
||||||
Codec.parseStructure(d, 0, d.length, this)
|
var d = ar[0] as DC;
|
||||||
..then((st) {
|
Codec.parseStructure(d, 0, d.length, this)
|
||||||
resource.instance?.setAttributes(st);
|
..then((st) {
|
||||||
rt.trigger(st);
|
resource.instance?.setAttributes(st);
|
||||||
})
|
rt.trigger(st);
|
||||||
..error((ex) => rt.triggerError(ex));
|
})
|
||||||
});
|
..error((ex) => rt.triggerError(ex));
|
||||||
|
} else {
|
||||||
|
rt.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
var attrs = DC.stringArrayToBytes(attributes);
|
var attrs = DC.stringArrayToBytes(attributes);
|
||||||
(sendRequest(IIPPacketAction.GetAttributes)
|
(sendRequest(IIPPacketAction.GetAttributes)
|
||||||
@ -2499,16 +2545,20 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
..addInt32(attrs.length)
|
..addInt32(attrs.length)
|
||||||
..addDC(attrs))
|
..addDC(attrs))
|
||||||
.done()
|
.done()
|
||||||
..then((ar) {
|
..then((ar) {
|
||||||
var d = ar[0] as DC;
|
if (ar != null) {
|
||||||
Codec.parseStructure(d, 0, d.length, this)
|
var d = ar[0] as DC;
|
||||||
..then((st) {
|
Codec.parseStructure(d, 0, d.length, this)
|
||||||
resource.instance?.setAttributes(st);
|
..then((st) {
|
||||||
|
resource.instance?.setAttributes(st);
|
||||||
|
|
||||||
rt.trigger(st);
|
rt.trigger(st);
|
||||||
})
|
})
|
||||||
..error((ex) => rt.triggerError(ex));
|
..error((ex) => rt.triggerError(ex));
|
||||||
});
|
} else {
|
||||||
|
rt.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
@ -2538,10 +2588,14 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
..addDateTime(fromDate)
|
..addDateTime(fromDate)
|
||||||
..addDateTime(toDate)
|
..addDateTime(toDate)
|
||||||
..done().then<dynamic>((rt) {
|
..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)
|
Codec.parseHistory(content, 0, content.length, resource, this)
|
||||||
.then((history) => reply.trigger(history));
|
.then((history) => reply.trigger(history));
|
||||||
|
} else {
|
||||||
|
reply.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
}).error((ex) => reply.triggerError(ex));
|
}).error((ex) => reply.triggerError(ex));
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
@ -2563,10 +2617,14 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
..addUint16(str.length)
|
..addUint16(str.length)
|
||||||
..addDC(str)
|
..addDC(str)
|
||||||
..done().then<dynamic>((args) {
|
..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)
|
Codec.parseResourceArray(content, 0, content.length, this)
|
||||||
.then((resources) => reply.trigger(resources));
|
.then((resources) => reply.trigger(resources));
|
||||||
|
} else {
|
||||||
|
reply.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
}).error((ex) => reply.triggerError(ex));
|
}).error((ex) => reply.triggerError(ex));
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
@ -2602,11 +2660,15 @@ class DistributedConnection extends NetworkConnection with IStore {
|
|||||||
|
|
||||||
(sendRequest(IIPPacketAction.CreateResource)..addDC(pkt.toDC())).done()
|
(sendRequest(IIPPacketAction.CreateResource)..addDC(pkt.toDC())).done()
|
||||||
..then((args) {
|
..then((args) {
|
||||||
var rid = args[0];
|
if (args != null) {
|
||||||
|
var rid = args[0];
|
||||||
|
|
||||||
fetch(rid).then((r) {
|
fetch(rid).then((r) {
|
||||||
reply.trigger(r);
|
reply.trigger(r);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
reply.triggerError(Exception("Null response"));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
|
@ -22,6 +22,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import '../../Resource/Instance.dart';
|
import '../../Resource/Instance.dart';
|
||||||
|
|
||||||
@ -371,12 +372,12 @@ class DistributedResource extends IResource {
|
|||||||
..addUint8(index)
|
..addUint8(index)
|
||||||
..addDC(parameters))
|
..addDC(parameters))
|
||||||
.done()
|
.done()
|
||||||
..then((res) {
|
..then((res) {
|
||||||
// not really needed, server will always send property modified,
|
// not really needed, server will always send property modified,
|
||||||
// this only happens if the programmer forgot to emit in property setter
|
// this only happens if the programmer forgot to emit in property setter
|
||||||
_properties[index] = value;
|
_properties[index] = value;
|
||||||
reply.trigger(null);
|
reply.trigger(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ import 'NetworkConnection.dart';
|
|||||||
|
|
||||||
class SendList extends BinaryList {
|
class SendList extends BinaryList {
|
||||||
NetworkConnection connection;
|
NetworkConnection connection;
|
||||||
AsyncReply<List<dynamic>>? reply;
|
AsyncReply<List<dynamic>?>? reply;
|
||||||
|
|
||||||
SendList(this.connection, this.reply) {}
|
SendList(this.connection, this.reply) {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
AsyncReply<List<dynamic>> done() {
|
AsyncReply<List<dynamic>?> done() {
|
||||||
connection.send(super.toDC());
|
connection.send(super.toDC());
|
||||||
|
|
||||||
return reply ?? AsyncReply.ready([]);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
@ -219,7 +219,7 @@ class TemplateGenerator {
|
|||||||
var con = await Warehouse.get<DistributedConnection>(
|
var con = await Warehouse.get<DistributedConnection>(
|
||||||
(path[1] as String) + "://" + (path[2] as String),
|
(path[1] as String) + "://" + (path[2] as String),
|
||||||
!isNullOrEmpty(username) && !isNullOrEmpty(password)
|
!isNullOrEmpty(username) && !isNullOrEmpty(password)
|
||||||
? {username: username, password: password}
|
? {"username": username, "password": password}
|
||||||
: null);
|
: null);
|
||||||
|
|
||||||
if (con == null) throw Exception("Can't connect to server");
|
if (con == null) throw Exception("Can't connect to server");
|
||||||
|
@ -40,4 +40,5 @@ abstract class IResource extends IDestructible {
|
|||||||
getProperty(String name);
|
getProperty(String name);
|
||||||
|
|
||||||
TemplateDescriber get template;
|
TemplateDescriber get template;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -386,6 +386,8 @@ class Instance extends IEventHandler {
|
|||||||
emitArgs("resourceModified", [_resource, pt.name, value]);
|
emitArgs("resourceModified", [_resource, pt.name, value]);
|
||||||
//_resource.emitArgs("modified", [pt.name, value]);
|
//_resource.emitArgs("modified", [pt.name, value]);
|
||||||
_resource.emitArgs(":${pt.name}", [value]);
|
_resource.emitArgs(":${pt.name}", [value]);
|
||||||
|
|
||||||
|
_resource.emitProperty(pt.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -65,7 +65,8 @@ class Warehouse {
|
|||||||
|
|
||||||
static KeyList<Type, FactoryEntry> _factory = _getBuiltInTypes();
|
static KeyList<Type, FactoryEntry> _factory = _getBuiltInTypes();
|
||||||
|
|
||||||
static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
|
static KeyList<String,
|
||||||
|
AsyncReply<IStore> Function(String, Map<String, dynamic>?)>
|
||||||
protocols = _getSupportedProtocols();
|
protocols = _getSupportedProtocols();
|
||||||
|
|
||||||
static bool _warehouseIsOpen = false;
|
static bool _warehouseIsOpen = false;
|
||||||
@ -222,7 +223,7 @@ class Warehouse {
|
|||||||
/// <param name="path"></param>
|
/// <param name="path"></param>
|
||||||
/// <returns>Resource instance.</returns>
|
/// <returns>Resource instance.</returns>
|
||||||
static AsyncReply<T?> get<T extends IResource>(String path,
|
static AsyncReply<T?> get<T extends IResource>(String path,
|
||||||
[attributes = null,
|
[Map<String, dynamic>? attributes = null,
|
||||||
IResource? parent = null,
|
IResource? parent = null,
|
||||||
IPermissionsManager? manager = null]) {
|
IPermissionsManager? manager = null]) {
|
||||||
var rt = AsyncReply<T?>();
|
var rt = AsyncReply<T?>();
|
||||||
@ -232,8 +233,8 @@ class Warehouse {
|
|||||||
var url = _urlRegex.allMatches(path).first;
|
var url = _urlRegex.allMatches(path).first;
|
||||||
|
|
||||||
if (protocols.containsKey(url[1])) {
|
if (protocols.containsKey(url[1])) {
|
||||||
var handler =
|
var handler = protocols[url[1]] as AsyncReply<IStore> Function(
|
||||||
protocols[url[1]] as AsyncReply<IStore> Function(String, dynamic);
|
String, Map<String, dynamic>?);
|
||||||
|
|
||||||
var getFromStore = () {
|
var getFromStore = () {
|
||||||
handler(url[2] as String, attributes)
|
handler(url[2] as String, attributes)
|
||||||
@ -360,7 +361,7 @@ class Warehouse {
|
|||||||
TypeTemplate? customTemplate = null,
|
TypeTemplate? customTemplate = null,
|
||||||
int age = 0,
|
int age = 0,
|
||||||
IPermissionsManager? manager = null,
|
IPermissionsManager? manager = null,
|
||||||
attributes = null]) {
|
Map<String, dynamic>? attributes = null]) {
|
||||||
var rt = AsyncReply<T?>();
|
var rt = AsyncReply<T?>();
|
||||||
|
|
||||||
if (resource.instance != null) {
|
if (resource.instance != null) {
|
||||||
@ -493,7 +494,7 @@ class Warehouse {
|
|||||||
[IStore? store = null,
|
[IStore? store = null,
|
||||||
IResource? parent = null,
|
IResource? parent = null,
|
||||||
IPermissionsManager? manager = null,
|
IPermissionsManager? manager = null,
|
||||||
attributes = null,
|
Map<String, dynamic>? attributes = null,
|
||||||
properties = null]) {
|
properties = null]) {
|
||||||
if (_factory[T] == null)
|
if (_factory[T] == null)
|
||||||
throw Exception("No Instance Creator was found for type ${T}");
|
throw Exception("No Instance Creator was found for type ${T}");
|
||||||
@ -640,15 +641,30 @@ class Warehouse {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static KeyList<String, AsyncReply<IStore> Function(String, dynamic)>
|
static KeyList<String,
|
||||||
|
AsyncReply<IStore> Function(String, Map<String, dynamic>?)>
|
||||||
_getSupportedProtocols() {
|
_getSupportedProtocols() {
|
||||||
var rt =
|
var rt = new KeyList<String,
|
||||||
new KeyList<String, AsyncReply<IStore> Function(String, dynamic)>();
|
AsyncReply<IStore> Function(String, Map<String, dynamic>?)>();
|
||||||
rt.add(
|
rt
|
||||||
"iip",
|
..add(
|
||||||
(String name, attributes) =>
|
"iip",
|
||||||
Warehouse.newResource<DistributedConnection>(
|
(String name, Map<String, dynamic>? attributes) =>
|
||||||
name, null, null, null, attributes));
|
Warehouse.newResource<DistributedConnection>(
|
||||||
|
name, null, null, null, attributes))
|
||||||
|
..add("iipws", (String name, Map<String, dynamic>? attributes) {
|
||||||
|
if (attributes == null) attributes = {};
|
||||||
|
attributes['ws'] = true;
|
||||||
|
return Warehouse.newResource<DistributedConnection>(
|
||||||
|
name, null, null, null, attributes);
|
||||||
|
})
|
||||||
|
..add("iipwss", (String name, Map<String, dynamic>? attributes) {
|
||||||
|
if (attributes == null) attributes = {};
|
||||||
|
attributes['wss'] = true;
|
||||||
|
return Warehouse.newResource<DistributedConnection>(
|
||||||
|
name, null, null, null, attributes);
|
||||||
|
});
|
||||||
|
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
pubspec.lock
31
pubspec.lock
@ -21,7 +21,7 @@ packages:
|
|||||||
name: args
|
name: args
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.3.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -36,13 +36,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
build:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: build
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.3"
|
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -92,13 +85,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.0.1"
|
||||||
dart_style:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: dart_style
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "2.0.3"
|
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -154,7 +140,7 @@ packages:
|
|||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.0"
|
version: "4.4.0"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -231,7 +217,7 @@ packages:
|
|||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.2.0"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -260,13 +246,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
source_gen:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: source_gen
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.5"
|
|
||||||
source_map_stack_trace:
|
source_map_stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -359,7 +338,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
@ -380,4 +359,4 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.12.0 <3.0.0"
|
dart: ">=2.14.0 <3.0.0"
|
||||||
|
11
pubspec.yaml
11
pubspec.yaml
@ -1,17 +1,18 @@
|
|||||||
name: esiur
|
name: esiur
|
||||||
description: Distributed Object Framework.
|
description: Distributed Object Framework.
|
||||||
version: 1.4.1
|
version: 1.4.5
|
||||||
#author: Ahmed Zamil <ahmed@esiur.com>
|
#author: Ahmed Zamil <ahmed@esiur.com>
|
||||||
homepage: https://github.com/esiur/esiur-dart
|
homepage: https://github.com/esiur/esiur-dart
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.14.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
source_gen:
|
# source_gen: ^1.0.5
|
||||||
args: #
|
args: ^2.3.0
|
||||||
pubspec_parse:
|
pubspec_parse: ^1.2.0
|
||||||
|
web_socket_channel: ^2.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test:
|
test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user