2016-05-15 11 views
0

Guten Tag. Ich baue eine iOS-Anwendung und wollte MQTT verwenden, um Nachrichten auf einem MQTT-Server zu abonnieren/veröffentlichen. Bei der Untersuchung von MQTT-Bibliotheken, I found this library, die für meine Zwecke angemessen schien. Bitte beachten Sie, dass ich mit CloudMQTT bereits einen MQTT-Server online eingerichtet habe. Nachdem ich herausgefunden hatte, wie CocoaPods funktionieren kann und wie ich Abhängigkeiten von meinem Podfile hinzufügen kann, habe ich es endlich eingerichtet.iOS - MQTT Client Framework verbindet/funktioniert

@interface VBViewController : UIViewController<MQTTSessionDelegate> 

und in meiner .m Datei, in der viewDidLoad Funktion, ich habe diese:

In der viewDidLoad Funktion meiner ersten Blick, ich durch das Hinzufügen dieser Zeile meiner .h Datei auf meinem MQTT Server zu verbinden versucht
MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init]; 
transport.host = @"mPortNumber.cloudmqtt.com"; 
transport.port = portNumber; 

session = [[MQTTSession alloc] init]; 
session.transport = transport; 

session.delegate=self; 

[session connectAndWaitTimeout:30]; 

[session subscribeToTopic:@"username/messagesFolder/#" atLevel:2 subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss){ 
    if (error) { 
     NSLog(@"Subscription failed %@", error.localizedDescription); 
    } else { 
     NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss); 
    } 
}]; 

Nach dem Ausführen wurde jedoch weder die Abonnement fehlgeschlagen/Erfolg Nachrichten angezeigt. Ich dachte, dass ich die falsche Portnummer verwendet haben könnte, also habe ich alle drei bereitgestellten Ports, den einfachen Port, einen SSL-Port und einen Websocket-Port verwendet. Nachdem nichts davon funktionierte, habe ich versucht, das Ordnerverzeichnis zu wechseln, indem ich mit den Schrägstrichen spielte, aber das hat auch nicht funktioniert.

Ich habe auch versucht, Nachrichten zu senden und zu empfangen, aber das hat auch nicht geklappt.

Ich benutze den Emulator für die mittlere Zeit, da ich meine iOS-Entwicklerlizenz noch nicht erneuert habe. Ich möchte nicht alle meine 10 Einsätze blasen, nur um dieses einfache Ding herauszufinden. Könnte das die Ursache für die fehlende Verbindung zu meinem MQTT Server sein? Ich würde das bezweifeln, weil der Emulator sich mit dem Internet verbinden und mit Safari surfen kann - also ist es ziemlich gut mit dem Internet verbunden.

Fehle ich etwas mit, wie ich die MQTT-Methoden initialisierte/importierte? Jede Hilfe wird sehr geschätzt.

Antwort

1

Sie erhalten keine Rückrufe, wenn Sie connectAndWaitTimeout verwenden.

Try connectWithConnectHandler(connectHandler: MQTTConnectHandler!), wie in einem Kommentar angegeben, erhalten Sie:

/** 
@return nothing and returns immediately. To check the connect results, register as an MQTTSessionDelegate and 
- watch for events 
- watch for connect or connectionRefused messages 
- watch for error messages 
or use the connectHandler block 
*/ 

auch sicher, dass Sie keine Verschlüsselung benötigen erfolgreich zu verbinden.

0

Ich habe es endlich geschafft zu arbeiten. Bitte verwenden Sie this project as reference. Mein MQTT-Broker wurde von CloudMQTT zur Verfügung gestellt. Sie können sich kostenlos für einen Server mit maximal 10 Geräteverbindungen anmelden. Bitte beachten Sie, dass Sie einen Benutzer erstellen müssen, um eine "Regel" oder einen "Nachrichtenordner" festlegen zu können. Beachten Sie auch die folgenden Details:

server : mPortNumber.cloudmqtt.com 
port : 1XXXX 

Ebenso wie der Benutzername, das Kennwort und der Ordner, den Sie gerade erstellt haben.

nun in Ihrem iOS-Anwendung, dann würden Sie die mqtt.plist Datei aktualisieren müssen:

host : mPortNumber.cloudmqtt.com/m14.cloudmqtt.com (whatever was provided) 
port : 1XXXX/13123 (use the ordinary one and NOT the SSL/Websocket Port) 
tls : NO 
base : yourFolderName 

Und dann suchen Sie nach diesem Code-Block in der viewDidLoad Funktion und aktualisieren Sie es als solche:

NSURL *bundleURL = [[NSBundle mainBundle] bundleURL]; 
NSURL *mqttPlistUrl = [bundleURL URLByAppendingPathComponent:@"mqtt.plist"]; 
self.mqttSettings = [NSDictionary dictionaryWithContentsOfURL:mqttPlistUrl]; 
self.request = self.mqttSettings[@"request"]; 
self.response = self.mqttSettings[@"response"]; 

/* 
* MQTTClient: create an instance of MQTTSessionManager once and connect 
* will is set to let the broker indicate to other subscribers if the connection is lost 
*/ 
if (!self.manager) { 
    self.manager = [[MQTTSessionManager alloc] init]; 
    self.manager.delegate = self; 
    self.manager.subscriptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:MQTTQosLevelExactlyOnce] forKey:[NSString stringWithFormat:@"%@/#", self.request]]; 
    [self.manager connectTo:self.mqttSettings[@"host"] 
         port:[self.mqttSettings[@"port"] intValue] 
         tls:[self.mqttSettings[@"tls"] boolValue] 
        keepalive:60 
         clean:true 
         auth:true 
         user:@"username" 
         pass:@"password" 
        willTopic:[NSString stringWithFormat:@"%@/", 
          self.request] 
         will:[@"offline" dataUsingEncoding:NSUTF8StringEncoding] 
        willQos:MQTTQosLevelExactlyOnce 
      willRetainFlag:FALSE 
       withClientId:nil]; 
     } else { 
    [self.manager connectToLast]; 
} 
/* 
* MQTTCLient: observe the MQTTSessionManager's state to display the connection status 
*/ 
[self.manager addObserver:self 
       forKeyPath:@"state" 
        options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew 
        context:nil]; 

Sie benötigen auch die observeValueForKeyPath Funktion, um herauszufinden, in welchem ​​Zustand wir uns befinden.

Dann kopieren Sie einfach die Funktion zum Senden von Nachrichten und zur Nachrichtenverarbeitung, um Nachrichten veröffentlichen und empfangene Nachrichten verarbeiten zu können.

0

Ich hatte das gleiche Problem. I löste es durch die subscribeToTopic Aufruf

- (void)connected:(MQTTSession *)session 

Methode (von MQTTSessionDelegate) bewegt. Es sieht so aus, als ob das Abonnement nicht funktioniert, wenn es direkt nach dem Verbindungsaufbau angerufen wird.