diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b196ca..c96f580 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +# 2.1.3 +- Resend subscription packets on reconnection. # 2.1.2 - Return MeteorClientLoginResult on logoutOtherClients. # 2.1.1 diff --git a/lib/src/ddp_client.dart b/lib/src/ddp_client.dart index c85f344..566952d 100644 --- a/lib/src/ddp_client.dart +++ b/lib/src/ddp_client.dart @@ -305,6 +305,11 @@ class DdpClient { var msg = json.encode(data); printDebug('Send: $msg'); _socket!.add(msg); + + // Resend all subscriptions + _subscriptionHandlers.forEach((id, handler) { + _sendMsgSub(id, handler.subName, handler.args); + }); } } diff --git a/lib/src/meteor_client.dart b/lib/src/meteor_client.dart index a02dab3..426299e 100644 --- a/lib/src/meteor_client.dart +++ b/lib/src/meteor_client.dart @@ -83,8 +83,6 @@ class MeteorClient { DateTime? _tokenExpires; UserLogInStatus _logInStatus = UserLogInStatus.loggedOut; - final Map _subscriptions = {}; - /// Meteor.collections final Map> _collections = {}; final Map>> _collectionsSubject = @@ -287,7 +285,6 @@ class MeteorClient { Function? onReady}) { var handler = connection.subscribe(name, args, onStop: onStop, onReady: onReady); - _subscriptions[handler.subId] = handler; return handler; } diff --git a/pubspec.yaml b/pubspec.yaml index 7443f68..6ce9a87 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: dart_meteor description: This library make connection between meteor backend and flutter app easily. Design to work seamlessly with StreamBuilder and FutureBuilder. -version: 2.1.2 +version: 2.1.3 homepage: https://github.com/tanutapi/dart_meteor environment: diff --git a/test/dart_meteor_test.dart b/test/dart_meteor_test.dart index 727d97e..aa12218 100644 --- a/test/dart_meteor_test.dart +++ b/test/dart_meteor_test.dart @@ -248,7 +248,8 @@ void main() { // expiration than the curren token. Otherwise, a bad guy with a // stolen token could use this method to stop his stolen token from // ever expiring. - expect(result2.tokenExpires.millisecondsSinceEpoch, lessThanOrEqualTo(result1.tokenExpires.millisecondsSinceEpoch)); + expect(result2.tokenExpires.millisecondsSinceEpoch, + lessThanOrEqualTo(result1.tokenExpires.millisecondsSinceEpoch)); }); }); @@ -291,13 +292,13 @@ void main() { }); group('subscription', () { - var meteor = MeteorClient.connect( - url: url, - debug: true, - ); + late MeteorClient meteor; setUp(() async { - meteor.reconnect(); + meteor = MeteorClient.connect( + url: url, + debug: true, + ); await Future.delayed(Duration(seconds: 2)); }); @@ -347,17 +348,13 @@ void main() { } }); - test('clearAllMessages', () async { - await meteor.loginWithPassword('user1', 'password1'); - await meteor.call('clearAllMessages'); - }); - test( 'collection(messages) stream should have values and "createdAt" should be instance of DateTime', () async { var completer = Completer(); expect(completer.future, completion(true)); await meteor.loginWithPassword('user1', 'password1'); + await meteor.call('clearAllMessages'); meteor.subscribe( 'messages', ); @@ -383,16 +380,44 @@ void main() { completer.complete(false); } }); + + test('meteor should resume subscription after reconnected', () async { + var completer = Completer(); + expect(completer.future, completion(true)); + await meteor.loginWithPassword('user1', 'password1'); + await meteor.call('clearAllMessages'); + meteor.subscribe( + 'messages', + ); + meteor.collection('messages').listen((value) { + var msgCnt = value.values.toList().length; + print('resume subscription, message count: $msgCnt'); + if (msgCnt == 2) { + completer.complete(true); + } + }); + await meteor.call('sendMessage', args: ['message 1']); + await Future.delayed(Duration(seconds: 2)); + meteor.disconnect(); + await Future.delayed(Duration(seconds: 2)); + meteor.reconnect(); + await Future.delayed(Duration(seconds: 2)); + await meteor.call('sendMessage', args: ['message 2']); + await Future.delayed(Duration(seconds: 2)); + if (!completer.isCompleted) { + completer.complete(false); + } + }); }); group('Reactive with rxdart', () { - var meteor = MeteorClient.connect( - url: url, - debug: true, - ); + late MeteorClient meteor; setUp(() async { - meteor.reconnect(); + meteor = MeteorClient.connect( + url: url, + debug: true, + ); await Future.delayed(Duration(seconds: 2)); });