Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for dynamic reconnectTime in method connect #18

Closed
jiajun-ifanr opened this issue Feb 4, 2021 · 11 comments
Closed

Support for dynamic reconnectTime in method connect #18

jiajun-ifanr opened this issue Feb 4, 2021 · 11 comments
Labels
enhancement New feature or request

Comments

@jiajun-ifanr
Copy link

Would it be good to support dynamic reconnectTime when calling the connect function?

For instance there is a scenario that one needs to retry 10 times when the network is suddenly disconnected.

The initial reconnectTime is set to 1 second. However in each retry this reconnectTime is increased by 1s.

For example, it will only take 1 second in the first retry. In the next retry it will take 2s. In the nth retry, it will take nth seconds.

And if possible, this reconnectTime is better to be set by users who pass a function to dynamically calculate it.

Currently from what I read, the reconnectTime can be set once only. Is there a way to do this?

@konsultaner konsultaner added the enhancement New feature or request label Feb 5, 2021
@konsultaner
Copy link
Owner

I'll think about it. Seems like a good idea.

@konsultaner
Copy link
Owner

@jiajun-ifanr I'm on it! Havn't had time to work on this yet. I hope you can wait a little longer

@jiajun-ifanr
Copy link
Author

@jiajun-ifanr I'm on it! Havn't had time to work on this yet. I hope you can wait a little longer

No problem! Thank you!

@konsultaner
Copy link
Owner

@jiajun-ifanr could you try this:

options: ClientConnectOptions(

@jiajun-ifanr
Copy link
Author

jiajun-ifanr commented Mar 25, 2021

@konsultaner I tried with the above example, but it seems like it will reconnect only when a session is being initialized. Also when a function is passed to _client.onNextTryToReconnect.listen, and while it is reconnecting, the function doesn't execute.

I want retries are made when a connection is ongoing and very suddenly the network is disconnected due to some network issues (e.g. connection lost / network change).

Is there any way to detect if the connection is lost and then retry connection?

@konsultaner
Copy link
Owner

What transport do you use? Actually it should also work on connection loss.

unawaited(transport.onConnectionLost.future.then((_) async {

@konsultaner
Copy link
Owner

No, you're right.. it does not push the event...

@konsultaner konsultaner reopened this Mar 25, 2021
@konsultaner
Copy link
Owner

I added a quick fix. but I need to write some tests on it... Should work if you use the latest master

@jiajun-ifanr
Copy link
Author

Looks like it works. Thanks again!

@jiajun-ifanr
Copy link
Author

jiajun-ifanr commented Mar 30, 2021

Hi @konsultaner , I find that after the client is reconnected, it doesn't seem to auto resubscribe to what it has already subscribed to. That's to say, it doesn't listen to data changes again.

Please take a glance at the below code as an example. It has a class called Wamp and it is first instantiated and connected to our server on page load. There's a Subscribe button and when you click on it, it will subscribe to a topic.

Here's a scenario where the network is suddenly disconnected (for e.g. 40 seconds). Then the network is back online, and the client begins to retry. Once it is successfully reconnected, it is supposed to listen data changes again. But it isn't.

Also when I click the Subscribe button again, a Bad state: No element exception is thrown. Any chance to get it worked?

import 'package:flutter/material.dart';
import 'package:connectanum/connectanum.dart';
import 'package:connectanum/json.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  Wamp wamp = new Wamp();

  @override
  void initState() {
    super.initState();
    wamp.connect();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test App'),
      ),
      body: Center(
          child: RaisedButton(
        onPressed: () {
          wamp.subscribe();
        },
        child: Text('Subscribe'),
      )),
    );
  }
}

class Wamp {
  Client client;
  Session session;

  void connect() async {
    String url =
        'wss://a4d2d62965ddb57fa4d6.ws.myminapp.com/ws/hydrogen/?x-hydrogen-client-id=a4d2d62965ddb57fa4d6&x-hydrogen-env-id=f1eeb28c9552d4c83df1&authorization=Hydrogen-r1%204prp5lsv9ox8n8r4y6ux6hwuguf9r8fg';

    client = Client(
      realm: 'com.ifanrcloud',
      transport: WebSocketTransport(
        url,
        new Serializer(),
        WebSocketSerialization.SERIALIZATION_JSON,
      ),
    );

    try {
      session = await client
          .connect(
            options: ClientConnectOptions(
              reconnectCount: 10,
              reconnectTime: Duration(
                milliseconds: 200,
              ),
            ),
          )
          .first;

      client.onNextTryToReconnect.listen((passedOptions) {
        print('retrying...');
        passedOptions.reconnectTime = Duration(
          milliseconds: passedOptions.reconnectTime.inMilliseconds + 500,
        );
      });
    } on Abort catch (abort) {
      print(abort.message.message);
    }
  }

  void subscribe() async {
    String topic = 'com.ifanrcloud.schema_event.danmu_jiajun.on_create';

    var options = new SubscribeOptions();
    options.addCustomValue("where", (serializerType) => "{}");

    Subscribed subscription = await session.subscribe(topic, options: options);
    print('subscribed successfully...');

    // listen to data change
    // supposed to listen to changes again on reconnection. But it isn't.
    subscription.eventStream.listen(
      (event) {
        print(event.argumentsKeywords.toString());
      },
    );
  }
}

I have tested my JS application counterpart and it works. So it might not be a backend related issue.
Is there a workaround for this?

@konsultaner
Copy link
Owner

Hi @konsultaner , I find that after the client is reconnected, it doesn't seem to auto resubscribe to what it has already subscribed to. That's to say, it doesn't listen to data changes again.

@jiajun-ifanr Yes this is totally expected behaviour. This feature is not implemented yet. You may open a new Issue for this feature if you want it. As soon as I get the time, I will implement it. There will be an additional subscribePermanently as soon as it is implemented. The same issue exists with registrations. They don't stay alive. For now, you may collect your subscriptions and resubscribe them manually in the reconnect event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants