目前,当具有相同客户端ID的MQTTClient对象重新初始化然后连接到代理时,似乎不会保留会话。
请考虑以下代码:
//Just a tiny wrapper around MQTTClient for custom methods
@property (nonatomic, strong) RAMQTTClient *client;
@implementation MQTTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//The selector gets called whenever a new message is received
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMessage:) name:@"didReceiveMessage" object:nil];
//Initialises an MQTT client with QOS=1 and cleanSession=NO
_client = [[RAMQTTClient alloc]initWithId:@"client-1"];
}
-(void)didReceiveMessage:(NSNotification *)notification {
NSString *data = (NSString *)notification.object;
NSLog(@"Received: %@", data);
}
// Use a switch action to subscribe and disconnect
- (IBAction)switchUpdated:(id)sender {
BOOL on = [sender isOn];
if (on) {
[_client listenToTopic:@"a~1"];
} else {
[_client disconnect];
}
}
@end
只要_client
对象未被销毁,断开连接和重新连接就会检索在该时间间隔内发送的脱机消息。但是,如果客户端重新初始化然后开始监听,我就不会收到任何离线消息。
以下是RAMQTTClient
的实施:
typedef void (^ConnectionCompletionHandler)(MQTTConnectionReturnCode code);
@interface RAMQTTClient()
@property (strong, nonatomic) MQTTClient *client;
@property (nonatomic) MQTTConnectionReturnCode connectionCode;
@end
@implementation RAMQTTClient
-(instancetype)initWithId:(NSString*)id {
if (self = [super init]) {
_client = [[MQTTClient alloc]initWithClientId:id cleanSession:NO];
}
return self;
}
-(BOOL)isRunning {
return _client.connected;
}
-(NSString *)id {
return _client.clientID;
}
-(void)connectWithCompletionHandler:(ConnectionCompletionHandler)handler {
if (!_client.connected) {
[_client connectToHost:@"localhost" completionHandler:handler];
}
}
-(void)listenToTopic:(NSString *)topic {
ConnectionCompletionHandler completionHandler = ^(MQTTConnectionReturnCode code) {
NSLog(@"RAMQTTClient: %@ connected", _client.clientID);
_connectionCode = code;
if (code == ConnectionAccepted) {
[_client subscribe:topic withQos:AtLeastOnce completionHandler:^(NSArray *grantedQos) {
NSLog(@"RAMQTTClient: Listening to %@", topic);
[_client setMessageHandler:^(MQTTMessage *message) {
NSLog(@"Message => %@",message.payloadString);
[[NSNotificationCenter defaultCenter]postNotificationName:@"didReceiveMessage"
object:message.payloadString];
}];
}];
}
};
[self connectWithCompletionHandler:completionHandler];
}
-(void)disconnect {
if (_client.connected) {
[_client disconnectWithCompletionHandler:^(NSUInteger code) {
NSLog(@"RAMQTTClient: %@ Disconnected with code %u", _client.clientID, code);
}];
}
}
@end
你们之前有没有遇到过这类问题?有解决方法吗?
答案 0 :(得分:1)
对于那些感兴趣的人,我已经明白了。问题是在订阅主题后设置了消息处理程序。由于离线消息在您订阅时立即到达,因此客户端在接收消息处理程序之前无法等待或设置消息处理程序。结果,即使消息到达,它们也不会被发送到处理程序。在订阅频道之前设置消息处理程序解决了这个问题。
[_client setMessageHandler:^(MQTTMessage *message) {
NSLog(@"Message => %@",message.payloadString);
[[NSNotificationCenter defaultCenter]postNotificationName:@"didReceiveMessage"
object:message.payloadString];
}];
[_client subscribe:topic withQos:AtLeastOnce completionHandler:^(NSArray *grantedQos) {
NSLog(@"RAMQTTClient: Listening to %@", topic);
}];