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

Set and Get presence state with Dart SDK #69

Open
Brinfotech1407 opened this issue Oct 16, 2021 · 9 comments
Open

Set and Get presence state with Dart SDK #69

Brinfotech1407 opened this issue Oct 16, 2021 · 9 comments
Assignees
Labels
status: waiting This issue waits for feedback from author. type: question This issue is a question.

Comments

@Brinfotech1407
Copy link

Our use case is to show the other member of a private (1 to 1) chat online or show the time when he/she was last online. Also, we want to ensure when a user puts the app in background state changes to offline and when the app is in foreground it changes to online. Also if the connection is closed due to inactivity it should show the user as offline.

With ref to below link how can i set and get the presence state for uuid with Dart SDK?

https://www.pubnub.com/docs/chat/features/presence

@are
Copy link
Contributor

are commented Oct 18, 2021

Hi! Thanks for reporting this issue!

So in general you are not able to persist state when you are offline. From the link you sent:

This custom state persists on a channel as long as the user stays subscribed to that channel.

Set and get state is not currently exposed in the SDK. If that is something that you require, then we will be happy to prioritize it.
But in general, you don't have to use Presence State to achieve what you described in your ticket (apart from last time online).

Background state changes can be handled by Flutter and usage of our custom Presence Widget. You should be able to detect if background state changes natively in Flutter (or using a plugin) and then change online flag in the widget.

@are are self-assigned this Oct 18, 2021
@are are added status: waiting This issue waits for feedback from author. type: question This issue is a question. labels Oct 18, 2021
@Brinfotech1407
Copy link
Author

@are thanks for the revert and we studied the presence widget, understand the main purpose is to inform server via announce heartbeat or leave.

Our next question is what should we use for receiving and updating online / offline state on all clients for this user. Along with the presence widget we see 3 other files on the repo, do we have to use a combination of them to send and receive presence updates? Is any documentation to explain the overall implementation?

Our implementation and issues we are facing:

We are already monitoring app state in flutter and able to detect if app is in start, resume, pause, stop as well as if subscription is happening in background isolate due to message received via FCM.

We are using hereNow for the active channel, user is currently looking at in UI and checking occupancy count with UUID to show online status of the other user, challenge is even when we subscribe with presence false and no heartbeat from background isolate after getting an FCM notification it starts showing user as online because occupancy increases based on subscription.

We are using hereNow with 100 seconds interval for detecting the channel occupancy , but it keeps showing the user online/offline until the next hereNow API call is made.
So what is the most optimal interval between two here now call or can we use some other method to show the user online/offline as soon as other user is online/offline ?

@Brinfotech1407
Copy link
Author

Brinfotech1407 commented Oct 22, 2021

@are , after some more testing and logging, we see inconsistencies in the way the client gets events on the presence channel from the server. Below are some examples:

1st problem receiving a join event after announcing leave, without any action from another device i.e. app is still in the background and no new message etc is sent or received.

*******************When Subscribed receive Join Event *******************************************************************
I/flutter ( 8698): │ 20-10-2021 12:36:14.130 (+0:21:40.906694)
I/flutter ( 8698): │ 💡 I/Foreground : presence:Listener PresenceAction.join Received From =>rfdSbV7Teihkrc8sxr7Vk4ddtsm1 => for channel: 81d4f935-6df7-4ea8-9f39-2d5c211b3864-pnpres Occupants=> 2

Sending Heartbeat to private channels*****************************************
I/flutter ( 8698): │ 20-10-2021 12:36:43.395 (+0:22:10.171627)
I/flutter ( 8698): │ 💡 I/Foreground : _sendHeartbeat: Private Channel => {81d4f935-6df7-4ea8-9f39-2d5c211b3864}

****************************Annoucing Leave ***************************************************************************************
I/flutter ( 8698): │ 20-10-2021 12:37:57.758 (+0:23:24.534480)
I/flutter ( 8698): │ 💡 I/Foreground : announceLeave: Private Channel => {81d4f935-6df7-4ea8-9f39-2d5c211b3864}

*********************************Received leave event *******************************************************************
I/flutter ( 8698): │ 20-10-2021 12:37:59.378 (+0:23:26.154840)
I/flutter ( 8698): │ 💡 I/Foreground : presence:Listener PresenceAction.leave Received From =>rfdSbV7Teihkrc8sxr7Vk4ddtsm1 => for channel: 81d4f935-6df7-4ea8-9f39-2d5c211b3864-pnpres Occupants=> 1

********** NOW THIS IS WHERE PROBLEM IS --> Received join event again without sending heartbeat or resubscribing ****************
I/flutter ( 8698): │ 20-10-2021 12:39:09.330 (+0:24:36.106714)
I/flutter ( 8698): │ 💡 I/Foreground : presence:Listener PresenceAction.join Received From =>rfdSbV7Teihkrc8sxr7Vk4ddtsm1 => for channel: 81d4f935-6df7-4ea8-9f39-2d5c211b3864-pnpres Occupants=> 2

2nd problem receiving presence on all subscribed channels, despite specifying a channel set for presence subscription separately, as mentioned earlier our use case we need presence only for private (1 to 1) channels only hence we specify those channels in presence channel set.

PubNub Channels Subscribed by this client

{eB9yTXzsHAaIjFqcA6lnHKNDxDf2, 3a99c6a0-096b-46a7-a2f0-5502d024fb12, 448b2b11-10d2-45d1-8cae-091ca645ab0c}

Sending Heartbeat to only private channel.

I/flutter ( 4175): │ 20-10-2021 19:29:37.488 (+0:01:06.852999)
I/flutter ( 4175): │ 💡 I/Foreground : _sendHeartbeat: Private Channel => {3a99c6a0-096b-46a7-a2f0-5502d024fb12}

Receiving join event for all channels

I/flutter (12088): │ 20-10-2021 20:35:00.060 (+0:00:10.890071)
I/flutter (12088): │ 💡 I/Foreground : presence:Listener PresenceAction.join Received From =>eB9yTXzsHAaIjFqcA6lnHKNDxDf2 => for channel: 448b2b11-10d2-45d1-8cae-091ca645ab0c-pnpres Occupants=> 2

I/flutter (12088): │ 20-10-2021 20:35:00.311 (+0:00:11.141646)
I/flutter (12088): │ 💡 I/Foreground : presence:Listener PresenceAction.join Received From =>eB9yTXzsHAaIjFqcA6lnHKNDxDf2 => for channel: 81d4f935-6df7-4ea8-9f39-2d5c211b3864-pnpres Occupants=> 2

3rd problem receiving timeout from same client within 30 seconds of receiving a join event (as per PubNub documentation timeout is 320 seconds after connection breaks with server), even though second client subscription is on and no action done on the client, because of this occupancy becomes 1

│ 20-10-2021 22:22:39.624 (+0:03:34.530803)
│ 💡 I/Foreground : presence:Listener PresenceAction.join Received From =>saurabhk => for channel: 5e654de1-dbf2-4937-b0b7-0ba9e1c1378c-pnpres Occupants=> 2

│ 20-10-2021 22:23:08.985 (+0:04:03.891403)
│ 💡 I/Foreground : presence:Listener PresenceAction.timeout Received From =>saurabhk => for channel: 5e654de1-dbf2-4937-b0b7-0ba9e1c1378c-pnpres Occupants=> 1

All these events make the tracking so inconsistent and confusing for us to figure out what exactly is going on.

@Brinfotech1407
Copy link
Author

@are have you seen our comments, waiting for your response.

@ramupal2603
Copy link

@are we have updated to latest stable version 4.0.0 and still facing same issues , waiting for your response.

@mohitpubnub
Copy link
Contributor

Hi,
So I gave it a try to replicate the issues which is described here related to inconsistency in tracking occupancy.
Can we have more log information specifically about widget/application lifecycle events.
e.g. To track what event is happening before we receive timeout event.
Because I am not seeing those problems while trying replicating it.

Also,

receiving a join event after announcing leave, without any action from another device

We may get join after announcing leave If the subscription is still active(on message arrival or on subscription interval it informs pubnub server about its existence).

@Brinfotech1407
Copy link
Author

Brinfotech1407 commented Dec 13, 2021

void didChangeAppLifecycleState(AppLifecycleState state) {
   if (state == AppLifecycleState.paused) {
     annouceLeave() // annoucing leave event when we app puts in background
   } else if (state == AppLifecycleState.resumed) {
     // resubscribePubnub();
     if ((_paused.difference(DateTime.now()).inMinutes).abs() >= 10) {
       _onNetworkConnected(); // re-subscribing if background to foreground comes after 10 mins
     } else {
       _client?.reconnect(); // re-connecting if we come less than 10 minutes from background to foreground
     }
     notificationService!.cancelAllNotifications();
   }
 }

when we puts a app in background we are announcing a leave event without unsubscribe , because if unsubscribe pubnub then we don't receive message from pubnub that's why i am not unsubscribing.

So i think related to our use case we needs to have a set and get state which will do our job , rather than depending Join and leave event.

@EgorLogachev
Copy link

Hi @are. What status of this issue? I wanna migrate our Flutter app to this package, but we use setting presence state https://www.pubnub.com/docs/presence/presence-state#setting-presence-state. Should we expect that it will be implemented and published soon?

@Brinfotech1407
Copy link
Author

Hi @are I seen that new release 4.2.1 got included setState and getState Function for presence one question I have that without passing UUID of other client how can I know the state. in latest SDK version below method is mentioned but it doesn't contains any UUID as a parameter can you help here , thanks.

Future<GetUserStateResult> getState( {Keyset? keyset, String? using, Set<String> channels = const {}, Set<String> channelGroups = const {}})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting This issue waits for feedback from author. type: question This issue is a question.
Projects
None yet
Development

No branches or pull requests

5 participants