diff --git a/lib/src/api_client/request/api_request.dart b/lib/src/api_client/request/api_request.dart index 5ce6e8f..540fe29 100644 --- a/lib/src/api_client/request/api_request.dart +++ b/lib/src/api_client/request/api_request.dart @@ -17,6 +17,7 @@ import 'package:hmi_core/hmi_core_failure.dart'; import 'package:hmi_core/hmi_core_log.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:hmi_core/hmi_core_result.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; // import 'package:web_socket_channel/web_socket_channel.dart'; // import 'package:web_socket_channel/io.dart'; /// @@ -84,6 +85,7 @@ class ApiRequest { Future> fetch() async { final queryJson = _query.buildJson(authToken: _authToken, debug: _debug, keep: _keep); final bytes = utf8.encode(queryJson); + _log.info('.fetch | platform: ${kIsWeb ? 'Web' : 'NonWeb'}'); if (kIsWeb) { return _fetchWebSocket(bytes); } else { @@ -96,6 +98,7 @@ class ApiRequest { Future> fetchWith(ApiQueryType query) async { final queryJson = query.buildJson(authToken: _authToken, debug: _debug, keep: _keep); final bytes = utf8.encode(queryJson); + _log.info('.fetchWith | platform: ${kIsWeb ? 'Web' : 'NonWeb'}'); if (kIsWeb) { return _fetchWebSocket(bytes); } else { @@ -118,45 +121,49 @@ class ApiRequest { } /// /// Fetching on web socket - Future> _fetchWebSocket(Bytes bytes) { - return WebSocket.connect('ws://${_address.host}:${_address.port}') - .then((wSocket) async { - return _sendWeb(wSocket, bytes) - .then((result) { - return switch(result) { - Ok() => _readWeb(wSocket) - .then((result) { - final Result r = switch(result) { - Ok(:final value) => Ok( - ApiReply.fromJson( - utf8.decode(value), - ), + Future> _fetchWebSocket(Bytes bytes) async { + return Future.microtask(() async { + final wSocket = WebSocketChannel.connect(Uri.parse('wss://${_address.host}:${_address.port}')); + _log.warning('._fetchWebSocket | wSocket connecting to ${_address.host}:${_address.port}...'); + try { + await wSocket.ready; + } on SocketException catch (err) { + _log.warning('._fetchWebSocket | wSocket connection error $err'); + return Err(Failure(message: 'ApiRequest._fetchWebSocket | Connection error $err', stackTrace: StackTrace.current)); + } on WebSocketChannelException catch (err) { + _log.warning('._fetchWebSocket | wSocket connection error $err'); + return Err(Failure(message: 'ApiRequest._fetchWebSocket | Connection error $err', stackTrace: StackTrace.current)); + } + _log.warning('._fetchWebSocket | wSocket connected to: ${wSocket}'); + return _sendWeb(wSocket, bytes) + .then((result) { + return switch(result) { + Ok() => _readWeb(wSocket) + .then((result) { + final Result r = switch(result) { + Ok(:final value) => Ok( + ApiReply.fromJson( + utf8.decode(value), ), - Err(:final error) => Err(error), - }; - return r; - }), - Err(:final error) => Future>.value( - Err(error), - ), - }; - }); - }) - .catchError((error) { - return Err( - Failure( - message: '.fetch | web socket error: $error', - stackTrace: StackTrace.current, - ), - ); - }); + ), + Err(:final error) => Err(error), + }; + return r; + }), + Err(:final error) => Future>.value( + Err(error), + ), + }; + }); + + }); } /// /// Reads bytes from web socket - Future, Failure>> _readWeb(WebSocket socket) async { + Future, Failure>> _readWeb(WebSocketChannel socket) async { try { List message = []; - final subscription = socket + final subscription = socket.stream .timeout( _timeout, onTimeout: (sink) { @@ -183,16 +190,19 @@ class ApiRequest { } /// /// Sends bytes over WEB socket - Future> _sendWeb(WebSocket socket, Bytes bytes) async { - final message = MessageBuild( - syn: FieldSyn.def(), - id: FieldId.def(), - kind: FieldKind.bytes, - size: FieldSize.def(), - data: FieldData([]), - ); + Future> _sendWeb(WebSocketChannel socket, Bytes bytes) async { + // final message = MessageBuild( + // syn: FieldSyn.def(), + // id: FieldId.def(), + // kind: FieldKind.bytes, + // size: FieldSize.def(), + // data: FieldData([]), + // ); try { - socket.add(message.build(bytes)); + _id++; + // final msgBytes = message.build(bytes, id: _id); + // _log.info('._send | Web socket bytes: ${msgBytes.sublist(0, 16)}'); + socket.sink.add(bytes); return Future.value(const Ok(true)); } catch (error) { _log.warning('._send | Web socket error: $error'); @@ -206,10 +216,9 @@ class ApiRequest { } /// /// Closes web socket - Future _closeSocketWeb(WebSocket? socket) async { + Future _closeSocketWeb(WebSocketChannel? socket) async { try { - socket?.close(); - // socket?.destroy(); + socket?.sink.close(); } catch (error) { _log.warning('[.close] error: $error'); } diff --git a/lib/src/table_schema/schema_entry.dart b/lib/src/table_schema/schema_entry.dart index 5a961bc..2e3c039 100644 --- a/lib/src/table_schema/schema_entry.dart +++ b/lib/src/table_schema/schema_entry.dart @@ -10,7 +10,7 @@ class SchemaEntry implements SchemaEntryAbstract { final _log = Log("$SchemaEntry"); final _id = const Uuid().v1(); // v1 time-based id final Map _map; - final bool _isEmpty; + bool _isEmpty; bool _isChanged = false; bool _isSelected = false; /// @@ -95,6 +95,9 @@ class SchemaEntry implements SchemaEntryAbstract { if (field != null) { final changed = field.update(value); _isChanged = _isChanged || changed; + if (_isChanged) { + _isEmpty = false; + } } _log.debug('.update | key: $key, \t field: $field, isChanged: $_isChanged'); } @@ -114,6 +117,6 @@ class SchemaEntry implements SchemaEntryAbstract { // @override String toString() { - return '$runtimeType{ isChanged: $_isChanged, isSelected: $_isSelected, map: $_map}'; + return '$runtimeType{ isEmpty: $_isEmpty, isChanged: $_isChanged, isSelected: $_isSelected, map: $_map}'; } }