我正在构建一个iOS应用程序,我想使用MQTT来订阅/发布消息到MQTT服务器。在研究MQTT库时,I found this library似乎足以满足我的需要。请注意,我已经使用CloudMQTT在线创建了一个MQTT服务器。在弄清楚如何使CocoaPods工作,以及如何在我的Podfile上添加依赖项之后,我终于开始运行了。在我的第一个视图的viewDidLoad
函数中,我尝试通过将此行添加到我的.h
文件来连接到我的MQTT服务器:
@interface VBViewController : UIViewController<MQTTSessionDelegate>
在我的.m
文件中,在viewDidLoad
函数中,我这样做了:
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);
}
}];
但是,在运行它时,订阅失败/成功消息都没有出现。我以为我可能使用了错误的端口号,所以我使用了提供的所有三个端口,简单端口,SSL端口和Websockets端口。在没有这些工作之后,我尝试通过使用斜杠来更改文件夹目录,但这也不起作用。
我也尝试过发送和接收邮件,但这也没有用。
我正在使用模拟器,因为我还没有更新我的iOS开发人员许可证。我不想仅仅为了解决这个简单的事情而打破我的所有10个部署。可能是连接到我的MQTT服务器失败的原因?我怀疑这是因为模拟器可以连接到互联网并使用Safari浏览就好了 - 所以它几乎连接到互联网。
我是否遗漏了初始化/导入MQTT方法的方法?
答案 0 :(得分:1)
使用connectAndWaitTimeout
时,您不会收到任何回调。
尝试使用评论中指定的connectWithConnectHandler(connectHandler: MQTTConnectHandler!)
,您将获得:
/**
@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
*/
另外,请确保您无需加密即可成功连接。
答案 1 :(得分:0)
我终于成功了。请使用this project as reference。我的MQTT代理由CloudMQTT提供。您可以免费注册服务器,最多可以有10个设备连接。请注意,您必须创建一个用户才能设置“规则”或“消息文件夹”。另外,请注意以下细节:
server : mPortNumber.cloudmqtt.com
port : 1XXXX
以及您刚创建的用户名,密码和文件夹。
现在,在您的iOS应用程序中,您需要更新mqtt.plist
文件:
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
然后在viewDidLoad
函数中查找此代码块并将其更新为:
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];
您还需要observeValueForKeyPath
函数来确定我们所处的状态。
然后只需复制消息发送和消息处理功能,即可发布消息并处理收到的消息。
答案 2 :(得分:0)
我遇到了同样的问题。我通过将subscribeToTopic调用移动到
来解决它- (void)connected:(MQTTSession *)session
方法(来自MQTTSessionDelegate)。看起来订阅在连接呼叫后立即调用时不起作用。
答案 3 :(得分:0)
这里发生了同样的问题,因为会话尚未准备好。
解决方案:只需在connectWithConnectHandler:块中实现subscriptionToTopic:
。MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init];
transport.host = @"test.mosquitto.org";
transport.port = 1883;
self.session = [[MQTTSession alloc] init];
self.session.delegate = self;
self.session.transport = transport;
[self.session connectWithConnectHandler:^(NSError *error) {
if(!error){
// ######## MQTT subscribe to topic ###########
[self.session subscribeToTopic:@"example/#" atLevel:MQTTQosLevelExactlyOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
if (error) {
NSLog(@"Subscription failed %@", error.localizedDescription);
} else {
NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
}
}];
}
}];