Last active
December 28, 2023 11:37
-
-
Save PlugFox/51038cb6f587332f6e803790a7d991e5 to your computer and use it in GitHub Desktop.
Long Polling example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Long Polling example | |
* https://gist.github.com/PlugFox/51038cb6f587332f6e803790a7d991e5 | |
* https://dartpad.dev?id=51038cb6f587332f6e803790a7d991e5 | |
* Matiunin Mikhail <plugfox@gmail.com>, 29 October 2023 | |
*/ | |
// ignore_for_file: avoid_print | |
import 'dart:async'; | |
import 'dart:convert'; | |
import 'dart:io'; | |
import 'dart:math' as math; | |
void main([List<String>? arguments]) { | |
final fn = polling(); | |
Future.doWhile(() async { | |
try { | |
final messages = await fn(); | |
messages.forEach(print); | |
} on Object {/* ignore */} | |
return true; | |
}); | |
} | |
Future<List<({int id, String text})>> Function() polling([ | |
Duration timeout = const Duration(seconds: 12), | |
]) { | |
const kEmptyList = <({int id, String text})>[]; | |
final url = Uri.parse('http://localhost:8080/getUpdates'); | |
final client = HttpClient(); | |
int? $lastId; | |
Uri createUrl() => url.replace(queryParameters: <String, Object?>{ | |
if ($lastId != null) 'id': $lastId?.toString(), | |
'timeout': timeout.inMilliseconds.toString(), | |
}); | |
return () async { | |
final request = await client.getUrl(createUrl()); | |
final response = await request.close(); | |
if (response.statusCode != HttpStatus.ok) throw Exception('bad_status_code'); | |
final body = await response.transform<String>(utf8.decoder).join(); | |
if (body.length < 3) return kEmptyList; | |
final messages = (jsonDecode(body) as Iterable) | |
.whereType<Map<String, Object?>>() | |
.expand<({int id, String text})>((e) => switch (e) { | |
{'id': int id, 'text': String text} => [(id: id, text: text)], | |
_ => kEmptyList, | |
}) | |
.toList(growable: false); | |
if (messages.isEmpty) return kEmptyList; | |
$lastId = <int>[ | |
if ($lastId != null) $lastId!, | |
...messages.map<int>((e) => e.id), | |
].reduce(math.max); | |
return messages; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment