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

MQTTSession vs MQTTSessionManager #47

Closed
beloso opened this issue Sep 23, 2015 · 22 comments
Closed

MQTTSession vs MQTTSessionManager #47

beloso opened this issue Sep 23, 2015 · 22 comments
Labels

Comments

@beloso
Copy link

beloso commented Sep 23, 2015

Hi,

In the first place, I'm sorry for opening an issue for this question. I'm not sure if this is the right place.

I am intrigued whether I should use MQTTSession ou MQTTSessionManager in my app. I want to keep a session to an MQTT broker, and I need to be notified of changes to the connection and handle reconnects and so on.

Which of the two classes should I use?

@zsk425
Copy link

zsk425 commented Sep 24, 2015

@tiagoveloso
I think you should use MQTTSessionManager. Because MQTTSessionManager has already handled the reconnection for you.You can see the demo here.

@ckrey ckrey added the question label Sep 24, 2015
@ckrey
Copy link
Contributor

ckrey commented Sep 24, 2015

Thanks for answering for me
😄

@beloso
Copy link
Author

beloso commented Sep 24, 2015

Wouldn't it be better to handle the SessionManager state with a delegate instead of an observer?

Just wondering.

@ckrey
Copy link
Contributor

ckrey commented Sep 24, 2015

Yes, this would be possible or could be done as an add-on.

The reason why I choose to do it via observer is that typically in a larger application, you would show the state in more than one view. All these views can register as an observer, but only one can be the delegate.

Obviously we could implement a set of delegates rather than just one...

@beloso
Copy link
Author

beloso commented Sep 24, 2015

I see your reasoning for this. In my case I am implementing a "singleton" MQTT manager object, though which I will expose my own API to send/receive messages. To me I could do with a delegate to handle session state on that singleton. But I understand why its done with an observer.

Thanks for your help in this.

@beloso beloso closed this as completed Sep 24, 2015
@beloso
Copy link
Author

beloso commented Sep 24, 2015

One last thing.

While using the session manager, the only thing I need in order to subscribe to a topic is to add a key/value pair to the subscriptions property?

In case I lose connection will the session manager resubscribe to those topics? Even between application launches? Or do I need to persist the subscribed topics somewhere?

@beloso beloso reopened this Sep 24, 2015
@ckrey
Copy link
Contributor

ckrey commented Sep 24, 2015

When you lose the connection, the SessionManager will reconnect. If you are using CleanSession=NO and the broker indicates an existing session, the subscriptions are still valid on the broker side. Otherwise the SessionManager will resubscribe on reconnect.

The list of subscriptions is NOT persisted. So you would have to set the list when the app is relaunched from scratch. (You don't need to do this when app is only backgrounded)

@beloso
Copy link
Author

beloso commented Sep 24, 2015

OK.

So when I add a topic to the subscriptions dictionary the manager will subscribe to it. I see.

Assume I am using CleanSession=NO and I relaunch the app (kill, and launch). My client will connect to the broker, the broker will still have a valid session and keep the topics subscribed. But the subscriptions dictionary will be empty? Am I correct?

Another question, assuming my subscriptions dictionary is empty, and I have some subscriptions in the broker, how would I unsubscribe them?

@ckrey
Copy link
Contributor

ckrey commented Sep 24, 2015

Yes, there is no interface in MQTT to ask the broker for active subscriptions.

If you want to start from scratch and don't know what you subscribed to before, connect once with CleanSession=YES using the same ClientID.

If you know what you subscribed to, just add and then remove the key/value pairs to the subscription property.

But I think it is quite application specific to handle changing subscriptions...

@beloso
Copy link
Author

beloso commented Oct 1, 2015

Yesterday I was playing around with this. I had something like this:

[MQTTClient connect]; // Connect MQTTSessionManager to my broker instance

[MQTTClient addSubscriptions:...]; // Adding subscriptions to the MQTTSessionManager subscriptions dictionary

And I noticed that I was not getting any subscription requests on my broker. However, moving the app into the background and then to the foreground (forcing an MQTTSessionManager reconnect) the subscriptions are sent.

Shouldn't MQTTSessionManagerhave an observer of some sorts on the subscriptions dictionary in order to detect and process new subscriptions/unsubscriptions?

@beloso beloso closed this as completed Oct 1, 2015
@beloso beloso reopened this Oct 1, 2015
@ogres
Copy link
Contributor

ogres commented Oct 1, 2015

Are you sure it was connected when you were trying to subscribe ?
Maybe it was not connected and without persistence it was not re-sent to the broker.
and after it re-connected , it re-sent the subscriptions data ,
you can actually check if subscription failed or not , subscribeAndWaitToTopics returns BOOL whether it succeeded or not,
MQTTSessionManager also contains NSMutableDictionary *subscriptions.

@beloso
Copy link
Author

beloso commented Oct 1, 2015

@ogres I am using MQTTSessionManager no MQTTSession.

MQTTSessionManager does not expose subscribeAndWaitToTopics:

@ogres
Copy link
Contributor

ogres commented Oct 1, 2015

yes but MQTTSession does , to test it , if it arrives or not , after making sure its connected you could use that.

@beloso
Copy link
Author

beloso commented Oct 1, 2015

I don't have access to an MQTTSession object, since MQTTSessionManager encapsulates it and does not expose it.

I have rearranged my code now I set up my subscriptions and connect afterwards. That works. But changing subscriptions in the MQTTSessionManage subscriptions will only take effect on after a reconnect

@ogres
Copy link
Contributor

ogres commented Oct 1, 2015

you should not change subscriptions dictionary directly , when you subscribe to a topic with a method call , it adds this topic to dictionary by itself , so you can see what topics are subscribed and session can re-subscribe them after re-connect. but again , dont change that dictionary , just call method to subscribe and topic will be added to the dictionary by the session manager.

@beloso
Copy link
Author

beloso commented Oct 1, 2015

But session manager does not have a method to subscribe, perhaps that's the problem.

@ogres
Copy link
Contributor

ogres commented Oct 1, 2015

My bad.I was thinking again about Session.

if you are using MQTTSessionManager you have to add topics to the dictionary before connection , so after it connects , it can subscribe to the topics.

If you want to subscribe/unsubscribe to the topics after its connected , you have to replace whole Dictionary and it will then unsubscribe the topics which are no longer in new dictionary and subscribe to new topics

see:

  • (void)setSubscriptions:(NSMutableDictionary *)newSubscriptions

@beloso
Copy link
Author

beloso commented Oct 1, 2015

That's what I find confusing. Wouldn't it be easier to just expose the subscribe/unsubscribe method from the session object within the SessionManager?

@ckrey
Copy link
Contributor

ckrey commented Oct 3, 2015

I clarified the interface by exposing an un-mutable NSDictionary.

@ckrey ckrey added the fixed label Oct 3, 2015
ckrey pushed a commit that referenced this issue Oct 3, 2015
>Release date: 2015-10-03

[NEW] provide support for tvOS, OSX and iOS closes #50
[NEW] add messageDelivered delegate message in MQTTSessionManager closes #49
[FIX] clarification of changing subscriptions in MQTTSessionManager closes #47
@ckrey ckrey closed this as completed Oct 8, 2015
ckrey pushed a commit that referenced this issue Oct 12, 2015
>Release date: 2015-10-10

[NEW] including tvOS with Cocoapods 0.39
[FIX] test coverage for topics containing 0x0000

[NEW] comment out tvOS until Cocoapods supports it
[NEW] inbound throttling closes #54

[NEW] provide support for tvOS, OSX and iOS closes #50
[NEW] add messageDelivered delegate message in MQTTSessionManager closes #49
[FIX] clarification of changing subscriptions in MQTTSessionManager closes #47
@marco-ni
Copy link

marco-ni commented Dec 1, 2015

Maybe this is not the right place for my question, but I haven't found a better one...I'm developing a multi-view app and I need to subscribe to different topics depending on the active view controller. The MQTTSession Manager is connected as the app starts (at that time subscriptions dictionary is empty).
I tried to add and remove topics in the viewWillAppear and viewWillDisappear of a view controller, topics are added but nothing happens.
I use this line to add topics:
[appDelegate.manager.subscriptions setObject:[NSNumber numberWithInt:MQTTQosLevelExactlyOnce]
forKey:@"myTopic"]];
and this one to remove them:
[appDelegate.manager.subscriptions removeObjectForKey:[NSString stringWithFormat:@"myTopic"]];

Should I force the MQTTSession Manager to disconnect and reconnect ?

@ckrey
Copy link
Contributor

ckrey commented Dec 2, 2015

@marco-ni please have a look at @ogres' responses above.
You should not modify subscriptions directly, but keep a private NSMutableDictionary with your subscriptions (which you manage by setObject/removeObjectForKey) and assign this to MQTTSessionManager's subscription property.
MQTTSessionManager will compare this new dictionary with the current subscriptions and perform the necessary SUBSCRIBE/UNSUBSCRIBE messages immediately

@marco-ni
Copy link

marco-ni commented Dec 2, 2015

Sorry, I missed it...and, most of all, my MQTTClient version was outdated. Now everything works fine, thanks a lot !!!

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

No branches or pull requests

5 participants