From e7192846fca5d570c30aac6d2775bf56e28c0ea3 Mon Sep 17 00:00:00 2001 From: Anita Ruangrotsakun <138700973+anitarua@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:39:27 -0800 Subject: [PATCH] chore: add basic topics example and readmes (#45) * chore: add basic topics example and readmes * dart format * use switch expression instead of switch statement * update link Co-authored-by: Matt Straathof <11823378+bruuuuuuuce@users.noreply.github.com> * update link Co-authored-by: Matt Straathof <11823378+bruuuuuuuce@users.noreply.github.com> * update link Co-authored-by: Matt Straathof <11823378+bruuuuuuuce@users.noreply.github.com> * fix example topics config name --------- Co-authored-by: Matt Straathof <11823378+bruuuuuuuce@users.noreply.github.com> --- examples/README.md | 5 ++ examples/flutter_chat_app/README.md | 16 ++++-- examples/topics/README.md | 28 ++++++++++ .../{topics.dart => topics/advanced.dart} | 53 +++++++++---------- examples/topics/basic_publisher.dart | 25 +++++++++ examples/topics/basic_subscriber.dart | 42 +++++++++++++++ 6 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 examples/README.md create mode 100644 examples/topics/README.md rename examples/{topics.dart => topics/advanced.dart} (58%) create mode 100644 examples/topics/basic_publisher.dart create mode 100644 examples/topics/basic_subscriber.dart diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..4fc479d --- /dev/null +++ b/examples/README.md @@ -0,0 +1,5 @@ +# Running the Examples + +For each example, you will need to provide a Momento API key, which you can generate from the [Momento Web Console](https://console.gomomento.com/api-keys). + +Each subfolder has more specific instructions, but you can run examples in Dart files using `dart run ` and start example Flutter apps using `flutter run -d `. \ No newline at end of file diff --git a/examples/flutter_chat_app/README.md b/examples/flutter_chat_app/README.md index 088f40a..823027b 100644 --- a/examples/flutter_chat_app/README.md +++ b/examples/flutter_chat_app/README.md @@ -1,15 +1,21 @@ -## Momento Topics Demo Chat App using Flutter +# Momento Topics Demo Chat App using Flutter -1. Install Flutter: https://docs.flutter.dev/get-started/install +## Prerequisites -2. Provide your Momento API key in [`lib/main.dart`](./lib/main.dart) at this line: +- [Installed Dart](https://dart.dev/get-dart) +- [Installed Flutter](https://docs.flutter.dev/get-started/install) +- Momento API key, which you can generate from the [Momento Web Console](https://console.gomomento.com/api-keys) + +## Running the Flutter Demo App + +1. Provide your Momento API key in [`lib/main.dart`](./lib/main.dart) at this line: ``` static const String _momentoApiKey = "your-api-key-here"; ``` -3. Run in [VSCode](https://docs.flutter.dev/tools/vs-code) or [Android Studio or IntelliJ](https://docs.flutter.dev/tools/android-studio). If using the command line, you can run using a command like: `flutter run -d macos` +2. Run in [VSCode](https://docs.flutter.dev/tools/vs-code) or [Android Studio or IntelliJ](https://docs.flutter.dev/tools/android-studio). If using the command line, you can run using a command like: `flutter run -d `. You can use `flutter devices` to see all connected devices and their IDs. -## Resources +## Flutter Resources - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) diff --git a/examples/topics/README.md b/examples/topics/README.md new file mode 100644 index 0000000..d5f9eca --- /dev/null +++ b/examples/topics/README.md @@ -0,0 +1,28 @@ +# Topics Examples + +## Prerequisites + +- [Installed Dart](https://dart.dev/get-dart) +- Momento API key, which you can generate from the [Momento Web Console](https://console.gomomento.com/api-keys) + +## Basic Example + +A very basic example of a Topics subscriber can be run using: + +``` +MOMENTO_API_KEY="your-api-key" dart run basic_subscriber.dart +``` + +A very basic example of a Topics publisher can be run using: + +``` +MOMENTO_API_KEY="your-api-key" dart run basic_publisher.dart +``` + +## Advanced Example + +The advanced example shows how you can unsubscribe from a topic (i.e. cancel a stream of messages) as well as how you can enable logging at a desired logging level. + +``` +MOMENTO_API_KEY="your-api-key" dart run advanced.dart +``` \ No newline at end of file diff --git a/examples/topics.dart b/examples/topics/advanced.dart similarity index 58% rename from examples/topics.dart rename to examples/topics/advanced.dart index fb0f1bd..85efdc7 100644 --- a/examples/topics.dart +++ b/examples/topics/advanced.dart @@ -17,9 +17,9 @@ void main() async { // start publishing messages in 2 seconds Timer(const Duration(seconds: 2), () async { // publish 10 messages spaced 1 second apart - for (final _ in Iterable.generate(10)) { + for (final i in Iterable.generate(10)) { var result = - await topicClient.publish("cache", "topic", StringValue("hi")); + await topicClient.publish("cache", "topic", StringValue("hi $i")); switch (result) { case TopicPublishSuccess(): print("Successful publish!"); @@ -30,34 +30,33 @@ void main() async { } }); - var sub = topicClient.subscribe("cache", "topic"); - switch (sub) { - case TopicSubscription(): - print("Successful subscription!"); + var subscription = topicClient.subscribe("cache", "topic"); + var messageStream = switch (subscription) { + TopicSubscription() => subscription.stream, + TopicSubscribeError() => throw Exception( + "Subscribe error: ${subscription.errorCode} ${subscription.message}"), + }; - // cancel subscription 10 seconds from now - Timer(const Duration(seconds: 10), () { - print("Cancelling subscription!"); - sub.unsubscribe(); - }); + // cancel subscription 15 seconds from now + Timer(const Duration(seconds: 15), () { + print("Cancelling subscription!"); + subscription.unsubscribe(); + }); - try { - await for (final msg in sub.stream) { - switch (msg) { - case TopicSubscriptionItemBinary(): - print("Binary value: ${msg.value}"); - case TopicSubscriptionItemText(): - print("String value: ${msg.value}"); - case TopicSubscriptionItemError(): - print("Error receiving message: ${msg.errorCode}"); - } - } - } catch (e) { - print("Runtime type: ${e.runtimeType}"); - print("Error with await for loop: $e"); + try { + await for (final msg in messageStream) { + switch (msg) { + case TopicSubscriptionItemBinary(): + print("Binary value: ${msg.value}"); + case TopicSubscriptionItemText(): + print("String value: ${msg.value}"); + case TopicSubscriptionItemError(): + print("Error receiving message: ${msg.errorCode}"); } - case TopicSubscribeError(): - print("Subscribe error: ${sub.errorCode} ${sub.message}"); + } + } catch (e) { + print("Runtime type: ${e.runtimeType}"); + print("Error with await for loop: $e"); } // unsubscribing should not affect the topic client's ability diff --git a/examples/topics/basic_publisher.dart b/examples/topics/basic_publisher.dart new file mode 100644 index 0000000..5c323b5 --- /dev/null +++ b/examples/topics/basic_publisher.dart @@ -0,0 +1,25 @@ +import 'dart:io'; +import 'package:client_sdk_dart/client_sdk_dart.dart'; + +void main() async { + var topicClient = TopicClient( + CredentialProvider.fromEnvironmentVariable("MOMENTO_API_KEY"), + MobileTopicConfiguration.latest()); + + // publish 10 messages spaced 1 second apart + for (final i in Iterable.generate(10)) { + var result = + await topicClient.publish("cache", "topic", StringValue("hi $i")); + switch (result) { + case TopicPublishSuccess(): + print("Successful publish!"); + case TopicPublishError(): + print("Publish error: ${result.errorCode} ${result.message}"); + } + sleep(Duration(seconds: 1)); + } + + topicClient.close(); + print("Closed Momento Topics publisher"); + exit(0); +} diff --git a/examples/topics/basic_subscriber.dart b/examples/topics/basic_subscriber.dart new file mode 100644 index 0000000..ad208a8 --- /dev/null +++ b/examples/topics/basic_subscriber.dart @@ -0,0 +1,42 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:client_sdk_dart/client_sdk_dart.dart'; + +void main() async { + var topicClient = TopicClient( + CredentialProvider.fromEnvironmentVariable("MOMENTO_API_KEY"), + MobileTopicConfiguration.latest()); + + var subscription = topicClient.subscribe("cache", "topic"); + var messageStream = switch (subscription) { + TopicSubscription() => subscription.stream, + TopicSubscribeError() => throw Exception( + "Subscribe error: ${subscription.errorCode} ${subscription.message}"), + }; + + // cancel subscription 15 seconds from now + Timer(const Duration(seconds: 15), () { + print("Cancelling subscription!"); + subscription.unsubscribe(); + }); + + try { + await for (final msg in messageStream) { + switch (msg) { + case TopicSubscriptionItemBinary(): + print("Binary value: ${msg.value}"); + case TopicSubscriptionItemText(): + print("String value: ${msg.value}"); + case TopicSubscriptionItemError(): + print("Error receiving message: ${msg.errorCode}"); + } + } + } catch (e) { + print("Runtime type: ${e.runtimeType}"); + print("Error with await for loop: $e"); + } + + topicClient.close(); + print("Closed Momento Topics subscriber"); + exit(0); +}