mirror of
https://github.com/esiur/esiur-dart.git
synced 2025-09-13 20:13:19 +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