Back

How to dynamically change Realtime Channels?

  • 0
  • Flutter
  • Realtime
panda_p
3 Jun, 2023, 16:19

Hello everyone. What is the correct way to dynamically add a channel to Realtime? Right now I am calling runtime.subscribe([<channel>]) for each new channel I want to listen to. This is working well when I have only one channel. Now I am trying to get this to work for a second channel. I am getting strange and confusing results. Sometimes it works, sometimes it doesn't.

Is the following approach fundamentally flawed? Realtime-Object is Singleton and created once for the (Flutter) App.

TypeScript
  @override
  Future<void> subscribeRealtime(
    final String channel,
    final Function(Map<String, dynamic> data) handler,
  ) async {
    // unsubscribe first is channel is known.
    // happens when internet-connection is lost and reestablished.
    if (channel2Subscription.containsKey(channel)) {
      await unsubscribeRealtime(channel);
    }

    final RealtimeSubscription subscription = realtime.subscribe([channel]);
    print('???# RealtimeRepositoryImpl subscribeRealtime($channel) #$hashCode with Realtime:#${realtime.hashCode}');
    
    // save subscription so we can close it later.
    channel2Subscription[channel] = subscription;
    
    // listen to the channel and call handler
    subscription.stream.listen(
      (final RealtimeMessage message) {
        print('???# RealtimeRepositoryImpl => event(): $channel');
        final Map<String, dynamic> payload = message.payload;
        handler(data);
      },
      onDone: () {
        print('???# !! RealtimeRepositoryImpl => onDone(): $channel');
      },
      onError: (Object error, StackTrace s) {
        print('???# !! RealtimeRepositoryImpl => onError(): $channel $error, $s');
      },
    );
    print('???#  => ${channel2Subscription.length}');
  }
TL;DR
The user is experiencing issues with dynamically changing Realtime Channels. They are using the `realtime.subscribe()` method to listen to multiple channels, but sometimes it works and sometimes it doesn't. The user suspects a concurrency problem causing the issue. They have tried delaying the second `subscribe` call via the debugger, but it doesn't help. The user is considering subscribing to the document channel as a whole, but they want to avoid unnecessary network traffic. They ask for hints and if their approach is acceptable. Solution: The user mentioned that multiple instances of Realtime may cause problems due to concurrency. They could try using separate instances rather than a
Drake
3 Jun, 2023, 16:23

Because of concurrency, there may be problems with multiple realtime instances. You could try to use separate rather than singleton

panda_p
3 Jun, 2023, 16:25

I read in another post that it is best to avoid multiple instanes of realtime. I am working on a mobile app and want to minimize my resources-impact when I can.

panda_p
3 Jun, 2023, 16:27

Is my approach of calling realtime.subscribe() with each individual channel acceptable?

Drake
3 Jun, 2023, 16:28

It should be but there could be a race condition with subscribing and unsubscribing

panda_p
3 Jun, 2023, 16:32

I can elaborate on the strange behaviours I mentioned:

When I start the app I subscribe to two different channels. After a short while, onDone() is called on both of them and realtime does not work anymore. This even happens when I delay the second subscribe via debugger.

However, when I subscribe to only one channel upon app start realtime works fine for that channel. If I then disable and enable the internet connection (triggering subscribe for both channels) sometimes realtime works fine, sometimes not. I think that is what happens. I lost track in all my debugging and testing I have done today.

Can you give me a hint?

panda_p
3 Jun, 2023, 16:35

As a last resort I am thinking about rewriting the code and just subscribe to the document-channel as a whole. I dont want to do that though, because that would mean a whole lot of unnecessary network traffic.

panda_p
3 Jun, 2023, 16:42

In the Screenshot: 1: the two subscribe()-calls 2: this line with "subscription: ws://..." appready only once, for the first subscription-channel. idk why 3: the two onDone() which I believe originte from the server, because I spend a whole lot of time making sure the app does not dispose / close the subscriptions

panda_p
3 Jun, 2023, 16:43

And I think this is interessting. Since I am developing this is the log from the self-hosted appwrite. Maybe you can tell me how to find more information.

Drake
3 Jun, 2023, 17:03

However, when I subscribe to only one channel upon app start realtime works fine for that channel. If I then disable and enable the internet connection (triggering subscribe for both channels) sometimes realtime works fine, sometimes not. I think that is what happens. I lost track in all my debugging and testing I have done today.

Internet problem might be something else altogether...I don't recall if we handle that error case

Drake
3 Jun, 2023, 17:04

ya...i think this missing channels is caused by the concurrency problem where one part of the code thinks there aren't any more channels but another does

panda_p
3 Jun, 2023, 17:56

Everything is on localhost via the android emulator.

panda_p
3 Jun, 2023, 17:57

Is there a way to avoid that? Like I said, delaying the second subscribe via breakpoint does not help.

Drake
3 Jun, 2023, 18:40

Breakpoints stop execution altogether. It doesn't let other code execute.

I don't think there's anything you can do outside of the SDK

panda_p
3 Jun, 2023, 20:33

thanks

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more