locality_core 1.0.4
locality_core: ^1.0.4 copied to clipboard
Realtime state synchronization across devices, powered by the Locality Social Cloud.
example/locality_core_example.dart
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:locality_core/locality_core.dart';
import 'package:locality_core/src/auth/exception/locality_authentication_exception.dart';
import 'package:locality_core/src/auth/data/user/authenticated_session_user.dart';
import 'package:locality_core/src/auth/data/user/public_user.dart';
import 'package:m511chacha20/chacha20_key.dart';
void main() async {
late LocalitySocialCloud cloud;
try {
cloud = await LocalitySocialCloud.startTest(
userCredentials: UserCredentials("SocialCloudDev", "123456"),
developerCredentials: DeveloperCredentials(
realmId: "public_test_realm",
realmSecret: "Zmbw951fsRPhCPake6rtBWc8YPKvUYChi45gN14znek="),
isRegistration: false);
} on LocalityAuthenticationException catch (exception) {
rethrow;
} catch (unexpectedError) {
rethrow;
}
final String chatPartner = "SocialCloudDev";
AuthenticatedSessionUser authenticatedSessionUser = cloud.getLoggedInUser();
KeyExchangeLobby findFriends = KeyExchangeLobby();
await LocalitySocialCloud.supervise(
pubSub: findFriends, key: ChaCha20Key.fromString("Hello World"));
if (!findFriends.containsUserById(authenticatedSessionUser.publicUser.id)) {
findFriends.announcePresence(authenticatedSessionUser);
}
if (findFriends.containsUserById(chatPartner)) {
ChaCha20Key? sharedKey =
await findFriends.getSharedKey(authenticatedSessionUser, chatPartner);
SimpleMessageExample messageExample =
SimpleMessageExample(authenticatedSessionUser, chatPartner);
await LocalitySocialCloud.supervise(pubSub: messageExample, key: sharedKey);
GreenTick greenTick = GreenTick();
Broadcast broadcast = messageExample.sendMessage(authenticatedSessionUser,
"Hello Malte. I am a new Locality Social Cloud developer!!");
broadcast.addObserver(greenTick);
await greenTick.future;
messageExample.printAllMessages();
}
}
class GreenTick implements BroadcastObserver {
final Completer<void> _completer = Completer<void>();
Future<void> get future => _completer.future;
@override
void onBroadcastChanged(Broadcast broadcast) {
if (broadcast.status == BroadcastStatus.confirmed) {
if (!_completer.isCompleted) {
_completer.complete();
}
}
}
}
class KeyExchangeLobby with PubSub {
Map<String, String> publicKeyByUserId = {};
int x = 546546;
@override
String getTopic() {
return "test:key-exchange-" + x.toString();
}
@override
void onReceive(Broadcast localityEvent) {
Map<String, dynamic> payload = localityEvent.getPayload();
switch (localityEvent.event) {
case "here":
publicKeyByUserId[payload["userId"]] = payload["publicKey"];
break;
}
}
void announcePresence(AuthenticatedSessionUser authenticateUser) {
send("here", {
"userId": authenticateUser.publicUser.id,
"publicKey": authenticateUser.publicUser.publicKey
});
}
bool containsUserById(String userId) {
return publicKeyByUserId.containsKey(userId);
}
Future<ChaCha20Key?> getSharedKey(
AuthenticatedSessionUser sessionUser, String targetUserId) async {
if (!containsUserById(targetUserId)) {
return null;
}
String publicKey = publicKeyByUserId[targetUserId]!;
return await sessionUser
.computeKeyForIsolate(PublicUser(targetUserId, publicKey));
}
}
class SimpleMessage {
final String userId;
final String message;
SimpleMessage({
required this.userId,
required this.message,
});
Map<String, dynamic> toMap() {
return {
'userId': userId,
'message': message,
};
}
factory SimpleMessage.fromMap(Map<String, dynamic> map) {
return SimpleMessage(
userId: map['userId'] ?? '',
message: map['message'] ?? '',
);
}
}
class SimpleMessageExample with PubSub {
List<SimpleMessage> messages = [];
late String topic;
SimpleMessageExample(
AuthenticatedSessionUser sessionUser, String targetUserId) {
// Ensure both users compoute the same topic name
bool targetUserIdIsBigger =
sessionUser.publicUser.id.compareTo(targetUserId) > 0;
String textToHash = targetUserIdIsBigger
? sessionUser.publicUser.id + targetUserId
: targetUserId + sessionUser.publicUser.id;
topic = sha256.convert(utf8.encode(textToHash)).toString();
}
int x = 546546;
@override
String getTopic() {
return 'test:$topic-messages-' + x.toString();
;
}
@override
void onReceive(Broadcast localityEvent) {
switch (localityEvent.event) {
case "message":
messages.add(SimpleMessage.fromMap(localityEvent.getPayload()));
break;
}
}
Broadcast sendMessage(AuthenticatedSessionUser authenticateUser, String text,
{BroadcastObserver? observer}) {
return send(
"message",
SimpleMessage(userId: authenticateUser.publicUser.id, message: text)
.toMap());
}
void printAllMessages() {
print("---------------------------------------------------------------");
for (var msg in messages) {
print('${msg.userId}: ${msg.message}');
}
}
}