How to use Dart socket onError as inline function? - sockets

I have dart socket that gets very long data. Lucky the third party add '\r\n' end of the data, so I can close when I find last data has '\r\n'.
In weeks I am trying to get long data due server problem. Before I used to waiting endlessly to server closes the connection (sometime took me 10 to 12 min)
Now seems everything works but a small problem. I used to get onError and onDone using void function. But I am using aqueduct so I need to return long data after I receive from server as a response.
In my below full code its keep printing "Server_Error". If I comment below data seems everything works. But my problem is that I need to return error data as well.
onError: () {
print("Server_Error");
},
onDone: () {
_socket.destroy();
},
cancelOnError: true);
If I comment above part I can print the long data.
My question is that, based on my scenario how to use Dart socket onError as inline function?
import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';
Socket _socket;
String _reply;
String _testValue = "";
main() async {
String _queryA = “QueryLongData”;
await Socket.connect("192.168.22.120”, 3000).then((Socket sock) {
_socket = sock;
_socket.write('$_queryA\r\n');
_socket.listen((data) {
final List<int> byteArray = data;
_reply = String.fromCharCodes(byteArray);
int dataLen = _reply.length;
int carriageReturnPosition = dataLen - 2;
int newLinePosition = dataLen - 1;
_testValue = _testValue + _reply;
if (_reply.substring(carriageReturnPosition, newLinePosition) == '\r' &&
_reply.substring(newLinePosition, dataLen) == '\n') {
_socket.close();
print("Data: $_testValue"); // means return data
}
}, onError: () {
print("Server_Error");
},
onDone: () {
_socket.destroy();
},
cancelOnError: true);
}).catchError((e) {
print("Server_Error");
});
if(_socket.done == true) {
print("Exiting...");
exit(0);
}
}

<!-- language: dart -->
String _queryA = "QueryLongData";
Socket.connect("192.168.22.120", 3000).then((Socket sock) {
_socket = sock;
_socket.write("$_queryA\r\n");
_socket.listen((data) {
final List<int> byteArray = data;
_reply = String.fromCharCodes(byteArray);
int dataLen = _reply.length;
int carriageReturnPosition = dataLen - 2;
int newLinePosition = dataLen - 1;
_testValue = _testValue + _reply;
if (_reply.substring(carriageReturnPosition, newLinePosition) == "\r" &&
_reply.substring(newLinePosition, dataLen) == "\n") {
_socket.close();
print("Data: $_testValue"); // means return data
}
}, onError: () => print("Server_Error"),
onDone: () => _socket.destroy(),
cancelOnError: true);
}).catchError((e) => print("Server_Error"));
if( ( await _socket.done enter code here) == true) {
print("Exiting...");
exit(0);
}

Related

Making FTP client with socket in Flutter

i'm making an FTP connection with sockets.
Everything works without TLS but when i start PASV in TLS mode, i can connect to data socket but i can't listen nothing.
Could someone help me to understand where i'm wrong?
This is the code i'm using:
String? pasvIP;
int? pasvPort;
RawSocket rawsock = await RawSocket.connect(ftpHost!, int.parse(port));
StreamSubscription<RawSocketEvent> rwlisten = rawsock.listen((event) {
if (event == RawSocketEvent.read) {
Uint8List? buffer = rawsock.read();
String result = String.fromCharCodes(buffer!);
print(' ${result}');
}
});
rawsock.write(Utf8Codec().encode('AUTH TLS\r\n'));
rawsock = await RawSecureSocket.secure(
rawsock,
onBadCertificate: (certificate) => true,
subscription: rwlisten,
);
rwlisten = rawsock.listen((event) {
if (event == RawSocketEvent.read) {
Uint8List? buffer = rawsock.read();
String result = String.fromCharCodes(buffer!);
print('${result}');
if (result.startsWith('227')) {
final startIndex = result.indexOf('(');
final endIndex = result.indexOf(')');
String ipPasv = result.substring(startIndex + 1, endIndex);
List ipPasvList = ipPasv.split(',');
pasvIP =
'${ipPasvList[0]}.${ipPasvList[1]}.${ipPasvList[2]}.${ipPasvList[3]}';
pasvPort =
(int.parse(ipPasvList[4]) * 256 + int.parse(ipPasvList[5]));
}
}
});
rawsock.write(Utf8Codec().encode('PBSZ 0\r\n'));
rawsock.write(Utf8Codec().encode('PROT P\r\n'));
rawsock.write(Utf8Codec().encode('USER ${username}\r\n'));
rawsock.write(
Utf8Codec().encode('PASS ${activeUser!.decrypt(password!)}\r\n'));
rawsock.write(Utf8Codec().encode('PASV\r\n'));
SecureSocket sockData = await SecureSocket.connect(
pasvIP!,
pasvPort!,
onBadCertificate: (certificate) => true,
);
sockData.listen(
(data) { // <-- NO DATA HERE
final serverResponse = String.fromCharCodes(data);
print('$serverResponse');
},
onError: (error) {
print(error);
sockData.destroy();
},
onDone: () {
print('Server left.');
sockData.destroy();
},
);
rawsock.write(Utf8Codec().encode('LIST\r\n'));
rawsock.write(Utf8Codec().encode('QUIT\r\n'));
Thanks
Marco

Return List<int> from reader.stream.listen with flutter_libserialport

I try to use flutter libserialport bull to implement Modbus RTU, however after calling the function it doesn't work.
List<int> receivedData = await readRegisters(0xFE, 0x0000, 0x001A);
print('Data: $receivedData');
When I call, nothing prints. However, it works if I use a private list and setState()!
await reader.stream.listen((data) {
print('stream : $data');
setState(() {
response!.addAll(data);
});
}).asFuture();
Output:
enter image description here
But after await as I called, I do want it to return for the instance variable. how I can solve it
Future<List<int>> readRegisters(int slaveID, int startAddress, int numberOfRegisters) async {
// construct the Modbus Read Holding Registers command
List<int> data = [slaveID,
0x03,
startAddress >> 8,
startAddress & 0xFF,
numberOfRegisters >> 8,
numberOfRegisters & 0xFF ];
int calculatedChecksum = calculateModbusChecksum(data);
data.add(calculatedChecksum & 0xFF);
data.add(calculatedChecksum >> 8);
// write the command to the serial port
port.write(command(data));
SerialPortReader reader = SerialPortReader(port, timeout: 1000);
List<int> response = [];
int bytesReceived = 0;
while (bytesReceived < numberOfRegisters) {
await reader.stream.listen((receivedData) {
print('received : $receivedData');
if (receivedData.isNotEmpty) {
response.addAll(receivedData);
bytesReceived += receivedData.length;
}
}).asFuture(response) ;
}
return response;
}
List<int> receivedData = await readRegisters(0xFE, 0x0000, 0x001A) as List<int>; Future.delayed(const Duration(seconds: 1),()=> print('Data: $receivedData'));
but they not return anything

HERE API Autosuggest Geocoding search

I am looking to use the HERE Geocoding Autosuggest. I understand how the API works and it is the implementation in Flutter I seek guidance on.
There is a Javascript example for the previous version
https://developer.here.com/documentation/examples/rest/geocoding_suggestions
This demonstrates the call and Json return, but I wondered if there were any Flutter examples/ guidance on implementation when it comes to displaying the data.
For example, the API returns address results for 'London', does Flutter have build in functionality to display these to the user (Such as TypeAheadField), in a dropdown style box below entry field for example, like the HERE screenshot below, where the user can select the correct suggestion? How would the call be implemented with this function?
I presume I will utilise an onChanged/SetState style function to call and display, but it is how to make the call as user types and then display the returned suggestion that I would find an example useful.
Any resources/ tips welcome
Thank you
Please check the below code ,which explains the use of auto suggest in the flutter.
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:here_sdk/core.dart';
import 'package:here_sdk/core.errors.dart';
import 'package:here_sdk/gestures.dart';
import 'package:here_sdk/mapview.dart';
import 'package:here_sdk/search.dart';
import 'SearchResultMetadata.dart';
// A callback to notify the hosting widget.
typedef ShowDialogFunction = void Function(String title, String message);
class SearchExample {
HereMapController _hereMapController;
MapCamera _camera;
MapImage? _poiMapImage;
List<MapMarker> _mapMarkerList = [];
late SearchEngine _onlineSearchEngine;
late OfflineSearchEngine _offlineSearchEngine;
bool useOnlineSearchEngine = true;
ShowDialogFunction _showDialog;
SearchExample(ShowDialogFunction showDialogCallback, HereMapController hereMapController)
: _showDialog = showDialogCallback,
_hereMapController = hereMapController,
_camera = hereMapController.camera {
double distanceToEarthInMeters = 5000;
MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
_camera.lookAtPointWithMeasure(GeoCoordinates(52.520798, 13.409408), mapMeasureZoom);
try {
_onlineSearchEngine = SearchEngine();
} on InstantiationException {
throw ("Initialization of SearchEngine failed.");
}
try {
// Allows to search on already downloaded or cached map data.
_offlineSearchEngine = OfflineSearchEngine();
} on InstantiationException {
throw ("Initialization of OfflineSearchEngine failed.");
}
_setTapGestureHandler();
_setLongPressGestureHandler();
_showDialog("Note", "Long press on the map to get the address for that location with reverse geocoding.");
}
Future<void> searchButtonClicked() async {
// Search for "Pizza" and show the results on the map.
_searchExample();
// Search for auto suggestions and log the results to the console.
_autoSuggestExample();
}
Future<void> geocodeAnAddressButtonClicked() async {
// Search for the location that belongs to an address and show it on the map.
_geocodeAnAddress();
}
void useOnlineSearchEngineButtonClicked() {
useOnlineSearchEngine = true;
_showDialog('Switched to SearchEngine', 'Requests will be calculated online.');
}
void useOfflineSearchEngineButtonClicked() {
useOnlineSearchEngine = false;
// Note that this app does not show how to download offline maps. For this, check the offline_maps_app example.
_showDialog(
'Switched to OfflineSearchEngine', 'Requests will be calculated offline on cached or downloaded map data.');
}
void _searchExample() {
String searchTerm = "Pizza";
print("Searching in viewport for: " + searchTerm);
_searchInViewport(searchTerm);
}
void _geocodeAnAddress() {
// Set map to expected location.
GeoCoordinates geoCoordinates = GeoCoordinates(52.53086, 13.38469);
double distanceToEarthInMeters = 1000 * 5;
MapMeasure mapMeasureZoom = MapMeasure(MapMeasureKind.distance, distanceToEarthInMeters);
_camera.lookAtPointWithMeasure(geoCoordinates, mapMeasureZoom);
String queryString = "Invalidenstraße 116, Berlin";
print("Finding locations for: $queryString. Tap marker to see the coordinates.");
_geocodeAddressAtLocation(queryString, geoCoordinates);
}
void _setTapGestureHandler() {
_hereMapController.gestures.tapListener = TapListener((Point2D touchPoint) {
_pickMapMarker(touchPoint);
});
}
void _setLongPressGestureHandler() {
_hereMapController.gestures.longPressListener = LongPressListener((GestureState gestureState, Point2D touchPoint) {
if (gestureState == GestureState.begin) {
GeoCoordinates? geoCoordinates = _hereMapController.viewToGeoCoordinates(touchPoint);
if (geoCoordinates == null) {
return;
}
_addPoiMapMarker(geoCoordinates);
_getAddressForCoordinates(geoCoordinates);
}
});
}
Future<void> _getAddressForCoordinates(GeoCoordinates geoCoordinates) async {
SearchOptions reverseGeocodingOptions = SearchOptions.withDefaults();
reverseGeocodingOptions.languageCode = LanguageCode.enGb;
reverseGeocodingOptions.maxItems = 1;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleReverseGeocodingResults(searchError, list);
});
} else {
_offlineSearchEngine.searchByCoordinates(geoCoordinates, reverseGeocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleReverseGeocodingResults(searchError, list);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleReverseGeocodingResults(SearchError? searchError, List<Place>? list) {
if (searchError != null) {
_showDialog("Reverse geocoding", "Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
_showDialog("Reverse geocoded address:", list!.first.address.addressText);
}
void _pickMapMarker(Point2D touchPoint) {
double radiusInPixel = 2;
_hereMapController.pickMapItems(touchPoint, radiusInPixel, (pickMapItemsResult) {
if (pickMapItemsResult == null) {
// Pick operation failed.
return;
}
List<MapMarker>? mapMarkerList = pickMapItemsResult.markers;
if (mapMarkerList.length == 0) {
print("No map markers found.");
return;
}
MapMarker topmostMapMarker = mapMarkerList.first;
Metadata? metadata = topmostMapMarker.metadata;
if (metadata != null) {
CustomMetadataValue? customMetadataValue = metadata.getCustomValue("key_search_result");
if (customMetadataValue != null) {
SearchResultMetadata searchResultMetadata = customMetadataValue as SearchResultMetadata;
String title = searchResultMetadata.searchResult.title;
String vicinity = searchResultMetadata.searchResult.address.addressText;
_showDialog("Picked Search Result", title + ". Vicinity: " + vicinity);
return;
}
}
double lat = topmostMapMarker.coordinates.latitude;
double lon = topmostMapMarker.coordinates.longitude;
_showDialog("Picked Map Marker", "Geographic coordinates: $lat, $lon.");
});
}
Future<void> _searchInViewport(String queryString) async {
_clearMap();
GeoBox viewportGeoBox = _getMapViewGeoBox();
TextQueryArea queryArea = TextQueryArea.withBox(viewportGeoBox);
TextQuery query = TextQuery.withArea(queryString, queryArea);
SearchOptions searchOptions = SearchOptions.withDefaults();
searchOptions.languageCode = LanguageCode.enUs;
searchOptions.maxItems = 30;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
_handleSearchResults(searchError, list, queryString);
});
} else {
_offlineSearchEngine.searchByText(query, searchOptions, (SearchError? searchError, List<Place>? list) async {
_handleSearchResults(searchError, list, queryString);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleSearchResults(SearchError? searchError, List<Place>? list, String queryString) {
if (searchError != null) {
// Note: When using the OfflineSearchEngine, the HERE SDK searches only on cached map data and
// search results may not be available for all zoom levels.
// Please also note that it may take time until the required map data is loaded.
// Subsequently, the cache is filled when a user pans and zooms the map.
_showDialog("Search", "Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
int listLength = list!.length;
_showDialog("Search for $queryString", "Results: $listLength. Tap marker to see details.");
// Add new marker for each search result on map.
for (Place searchResult in list) {
Metadata metadata = Metadata();
metadata.setCustomValue("key_search_result", SearchResultMetadata(searchResult));
// Note: getGeoCoordinates() may return null only for Suggestions.
_addPoiMapMarkerWithMetadata(searchResult.geoCoordinates!, metadata);
}
}
Future<void> _autoSuggestExample() async {
GeoCoordinates centerGeoCoordinates = _getMapViewCenter();
SearchOptions searchOptions = SearchOptions.withDefaults();
searchOptions.languageCode = LanguageCode.enUs;
searchOptions.maxItems = 5;
TextQueryArea queryArea = TextQueryArea.withCenter(centerGeoCoordinates);
if (useOnlineSearchEngine) {
// Simulate a user typing a search term.
_onlineSearchEngine.suggest(
TextQuery.withArea(
"p", // User typed "p".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_onlineSearchEngine.suggest(
TextQuery.withArea(
"pi", // User typed "pi".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_onlineSearchEngine.suggest(
TextQuery.withArea(
"piz", // User typed "piz".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
} else {
// Simulate a user typing a search term.
_offlineSearchEngine.suggest(
TextQuery.withArea(
"p", // User typed "p".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_offlineSearchEngine.suggest(
TextQuery.withArea(
"pi", // User typed "pi".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
_offlineSearchEngine.suggest(
TextQuery.withArea(
"piz", // User typed "piz".
queryArea),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
_handleSuggestionResults(searchError, list);
});
}
}
void _handleSuggestionResults(SearchError? searchError, List<Suggestion>? list) {
if (searchError != null) {
print("Autosuggest Error: " + searchError.toString());
return;
}
// If error is null, list is guaranteed to be not empty.
int listLength = list!.length;
print("Autosuggest results: $listLength.");
for (Suggestion autosuggestResult in list) {
String addressText = "Not a place.";
Place? place = autosuggestResult.place;
if (place != null) {
addressText = place.address.addressText;
}
print("Autosuggest result: " + autosuggestResult.title + " addressText: " + addressText);
}
}
Future<void> _geocodeAddressAtLocation(String queryString, GeoCoordinates geoCoordinates) async {
_clearMap();
AddressQuery query = AddressQuery.withAreaCenter(queryString, geoCoordinates);
SearchOptions geocodingOptions = SearchOptions.withDefaults();
geocodingOptions.languageCode = LanguageCode.deDe;
geocodingOptions.maxItems = 30;
if (useOnlineSearchEngine) {
_onlineSearchEngine.searchByAddress(query, geocodingOptions, (SearchError? searchError, List<Place>? list) async {
_handleGeocodingResults(searchError, list, queryString);
});
} else {
_offlineSearchEngine.searchByAddress(query, geocodingOptions,
(SearchError? searchError, List<Place>? list) async {
_handleGeocodingResults(searchError, list, queryString);
});
}
}
// Note that this can be called by the online or offline search engine.
void _handleGeocodingResults(SearchError? searchError, List<Place>? list, String queryString) {
if (searchError != null) {
_showDialog("Geocoding", "Error: " + searchError.toString());
return;
}
String locationDetails = "";
// If error is null, list is guaranteed to be not empty.
for (Place geocodingResult in list!) {
// Note: getGeoCoordinates() may return null only for Suggestions.
GeoCoordinates geoCoordinates = geocodingResult.geoCoordinates!;
Address address = geocodingResult.address;
locationDetails = address.addressText +
". GeoCoordinates: " +
geoCoordinates.latitude.toString() +
", " +
geoCoordinates.longitude.toString();
print("GeocodingResult: " + locationDetails);
_addPoiMapMarker(geoCoordinates);
}
int itemsCount = list.length;
_showDialog("Geocoding result for $queryString. Results: $itemsCount", locationDetails);
}
Future<MapMarker> _addPoiMapMarker(GeoCoordinates geoCoordinates) async {
// Reuse existing MapImage for new map markers.
if (_poiMapImage == null) {
Uint8List imagePixelData = await _loadFileAsUint8List('poi.png');
_poiMapImage = MapImage.withPixelDataAndImageFormat(imagePixelData, ImageFormat.png);
}
MapMarker mapMarker = MapMarker(geoCoordinates, _poiMapImage!);
_hereMapController.mapScene.addMapMarker(mapMarker);
_mapMarkerList.add(mapMarker);
return mapMarker;
}
Future<Uint8List> _loadFileAsUint8List(String fileName) async {
// The path refers to the assets directory as specified in pubspec.yaml.
ByteData fileData = await rootBundle.load('assets/' + fileName);
return Uint8List.view(fileData.buffer);
}
Future<void> _addPoiMapMarkerWithMetadata(GeoCoordinates geoCoordinates, Metadata metadata) async {
MapMarker mapMarker = await _addPoiMapMarker(geoCoordinates);
mapMarker.metadata = metadata;
}
GeoCoordinates _getMapViewCenter() {
return _camera.state.targetCoordinates;
}
GeoBox _getMapViewGeoBox() {
GeoBox? geoBox = _camera.boundingBox;
if (geoBox == null) {
print(
"GeoBox creation failed, corners are null. This can happen when the map is tilted. Falling back to a fixed box.");
GeoCoordinates southWestCorner = GeoCoordinates(
_camera.state.targetCoordinates.latitude - 0.05, _camera.state.targetCoordinates.longitude - 0.05);
GeoCoordinates northEastCorner = GeoCoordinates(
_camera.state.targetCoordinates.latitude + 0.05, _camera.state.targetCoordinates.longitude + 0.05);
geoBox = GeoBox(southWestCorner, northEastCorner);
}
return geoBox;
}
void _clearMap() {
_mapMarkerList.forEach((mapMarker) {
_hereMapController.mapScene.removeMapMarker(mapMarker);
});
_mapMarkerList.clear();
}
}
For more details please check enter link description here

How can I get multiple messages from dart isolate?

How can I get multiple messages from dart isolate?
I'm trying to create an excel file and want to do some operation on that file in an isolate. Before doing an operation on that file, I want to return an message to main isolate, that excel file is created.
Here is function goes in isolate :
foo(String filePath){
// create excel file
var bytes = File(filePath).readAsBytesSync();
var excel = Excel.decodeBytes(bytes);
//HERE I WANT TO SEND THE MESSAGE THAT CREATING EXCEL FILE IS DONE
// some operatoin on excel file
var result = doSomeOperation(excel);
return result;
}
Main isolate code :
var result = await compute(foo, filePath);
What should I do to get creating file message before the actual result comes?
For excel, I'm using excel: ^2.0.0-null-safety-3 package.
Compute only returns one result. If you want to pass multiple 'events' back to the main isolate then you need to use the full Isolate logic (with sendPort and receivePort).
For example, the following code runs in an isolate, and downloads a file while emitting float values to represent progress, potentially a String to indicate log messages and then a bool to indicate success or failure upon completion.
Future<void> isolateDownload(
DownloadRequest request) async {
final sendPort = request.sendPort;
if (sendPort != null) {
var success = false;
var errorMessage = '';
var url = Uri.parse('a_url_based_on_request');
IOSink? out;
try {
http.StreamedResponse response =
await http.Client().send(http.Request('GET', url));
if (response.statusCode == 200) {
var filePath =
join(request.destinationDirPath, '${request.fileName}.ZIP');
var contentLength = response.contentLength;
var bytesLoadedUpdateInterval = (contentLength ?? 0) / 50;
var bytesLoaded = 0;
var bytesLoadedAtLastUpdate = 0;
out = File(filePath).openWrite();
await response.stream.forEach((chunk) {
out?.add(chunk);
bytesLoaded += chunk.length;
// update if enough bytes have passed since last update
if (contentLength != null &&
bytesLoaded - bytesLoadedAtLastUpdate >
bytesLoadedUpdateInterval) {
sendPort.send(bytesLoaded / contentLength);
bytesLoadedAtLastUpdate = bytesLoaded;
}
});
success = true;
if (contentLength != null) {
sendPort.send(1.0); // send 100% downloaded message
}
} else {
errorMessage =
'Download of ${request.fileName} '
'received response ${response.statusCode} - ${response.reasonPhrase}';
}
} catch (e) {
errorMessage = 'Download of ${request.chartType}:${request.chartName} '
'received error $e';
} finally {
await out?.flush();
await out?.close();
if (errorMessage.isNotEmpty) {
sendPort.send(errorMessage);
}
sendPort.send(success);
}
}
}
The code that spawns the isolate then simply checks for the type of the message passed to it to determine the action.
Future<bool> _downloadInBackground(
DownloadRequest request) async {
var receivePort = ReceivePort();
request.sendPort = receivePort.sendPort;
var isDone = Completer();
var success = false;
receivePort.listen((message) {
if (message is double) {
showUpdate(message);
}
if (message is String) {
log.fine(message); // log error messages
}
if (message is bool) {
success = message; // end with success or failure
receivePort.close();
}
}, onDone: () => isDone.complete()); // wraps up
await Isolate.spawn(isolateDownload, request);
await isDone.future;
return success;
}

How to send big text data from tcp socket to Flutter app?

I have a 3000 rows and 20 column data most cell has 50 or 80 character long text. I test using aqueduct and Dart Server to see which one is better intermediate option in between server data and Flutter communication.
I use 2 option for the test. All I can test is that for (var data in _socket) runs about 10 or 12 times to receive whole data. On the other hand _socket.liste lost much of the data.
In both I even use await Future.delayed(Duration(seconds: 7))...
And result was same. In short data they're both very fast. but for big data I am having problem to get correct result.
How to send big text data from tcp socket to Flutter app?
// OPTION 1
_socket.listen((List<int> data) {
String _reply = new String.fromCharCodes(data).trim();
_reply = "$_reply$_tmpValue";
});
// OPTION 2
await for (var data in _socket) {
String _reply = new String.fromCharCodes(data).trim();
_reply = "$_reply$_tmpValue";
}
UPDATE:
final Socket client = await Socket.connect('192.168.22.120', 3000);
client.add(utf8.encode('$_requestedData\r\n'));
client.listen(
(var data) {
var ints = new Uint8List.fromList(data).buffer.asInt64List();
ints.forEach((i) => print('Got $i'));
},
onDone: () { print('Done'); client.close(); },
onError: (e) { print('Got error $e'); client.close(); });
print('main done');
RESULT
main done
_reply:
Got 4206144564389427761
Got 6861850004482897203
Got 2368148215793798714
UPDATE (Working Solution):
_socket = await Socket.connect('127.0.0.1’, 3000);
_socket.write(_myQuery);
await for (var data in _socket) {
_reply = new String.fromCharCodes(data);
_rawValue = _rawValue + _reply;
int dataLen;
dataLen = _reply.length;
int carriageReturnPosition;
carriageReturnPosition = dataLen - 2;
int newLinePosition;
newLinePosition = dataLen - 1;
// In my scenario it loops 32 times and it takes about 145 seconds to get big data
if (_reply.substring(carriageReturnPosition, newLinePosition) == '\r' &&
_reply.substring(newLinePosition, dataLen) == '\n') {
await _socket.close();
_returnData = _reply;
}
}