mobile-web-messaging / mqttkit Goto Github PK
View Code? Open in Web Editor NEWMQTT Objective-C client for iOS
License: Apache License 2.0
MQTT Objective-C client for iOS
License: Apache License 2.0
Hi,
Mosquitto 1.4 has been released. http://mosquitto.org/2015/02/version-1-4-released/ , can be upgraded to 1.4? thanks.
Hi,
I found that app will crash every time when network lost or unstable.
The log trace at this line in file net_mosq.c:
297:rc = connect(*sock, rp->ai_addr, rp->ai_addrlen);
Full Crash log is here,hope you guys can help:
Thread 0:
0 libsystem_kernel.dylib 0x3956c148 connect + 8
1 EwChat 0x00157fcc _mosquitto_try_connect (net_mosq.c:305)
2 EwChat 0x00158178 _mosquitto_socket_connect (net_mosq.c:354)
3 EwChat 0x00156de0 _mosquitto_reconnect (mosquitto.c:513)
4 EwChat 0x00156ba8 mosquitto_connect_bind (mosquitto.c:439)
5 EwChat 0x00156b4a mosquitto_connect (mosquitto.c:426)
6 EwChat 0x001544f4 -MQTTClient connectWithCompletionHandler:
7 EwChat 0x001546ca -MQTTClient connectToHost:completionHandler:
8 EwChat 0x0005035a -MqttService doConnect
9 CoreFoundation 0x2e7e3f3e __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER + 10
10 CoreFoundation 0x2e757da4 _CFXNotificationPost + 1716
11 Foundation 0x2f142cc0 -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
12 Foundation 0x2f1475c2 -[NSNotificationCenter postNotificationName:object:] + 26
13 EwChat 0x000978fc -EwChatAppDelegate applicationWillEnterForeground:
14 UIKit 0x312b243e -[UIApplication _sendWillEnterForegroundCallbacks] + 90
15 UIKit 0x31257964 -[UIApplication _handleApplicationResumeEvent:] + 1144
16 UIKit 0x3105660e -[UIApplication handleEvent:withNewEvent:] + 1878
17 UIKit 0x31055df4 -[UIApplication sendEvent:] + 68
18 UIKit 0x310ba400 _UIApplicationHandleEvent + 612
19 GraphicsServices 0x336c3b52 _PurpleEventCallback + 606
20 GraphicsServices 0x336c373a PurpleEventCallback + 30
21 CoreFoundation 0x2e7ec844 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 32
22 CoreFoundation 0x2e7ec7de __CFRunLoopDoSource1 + 342
23 CoreFoundation 0x2e7eafaa __CFRunLoopRun + 1402
24 CoreFoundation 0x2e755764 CFRunLoopRunSpecific + 520
25 CoreFoundation 0x2e755546 CFRunLoopRunInMode + 102
26 GraphicsServices 0x336c26ce GSEventRunModal + 134
27 UIKit 0x310b488c UIApplicationMain + 1132
28 EwChat 0x000a17c0 main (main.m:18)
29 libdyld.dylib 0x394b6ab4 start + 0
Hello,
I was trying to submit to the app store via Xcode organizer and it kept stating that I had an invalid CFBundleShortVersion number (0.1.0-next). After investigating the issue (considering my project version and build was 1.3.2 build 1) I noticed that you guys use an invalid versioning system (invalid in the eyes of apple).
This doesn't affect anything except when uploading to the app store. More like an FYI
If anyone else is having this issue, simply navigate to the Pods project, select the MQTT target and change the version number from 0.1.0-next to 0.1.0 or whatever arbitrary number you want so long as it's valid in Apple's eyes.
A way to let MQTT work in background can be to set it up as VoIP service with this settings:
- Enable the Voice over IP background mode for your app. (Because VoIP apps involve audio content, it is recommended that you also enable the Audio and AirPlay background mode.) You enable background modes in the Capabilities tab of your Xcode project.
- Configure one of the app’s sockets for VoIP usage.
- Before moving to the background, call the setKeepAliveTimeout:handler: method to install a handler to be executed periodically. Your app can use this handler to maintain its service connection.
But libmosquitto uses socket() from socket.h to create the socket and not one of the following:
Configuring stream interfaces for VoIP usage
- NSInputStream and NSOutputStream
For Cocoa streams, use the setProperty:forKey: method to add the NSStreamNetworkServiceType property to the stream. The value of this property should be set to NSStreamNetworkServiceTypeVoIP.- NSURLRequest
When using the URL loading system, use the setNetworkServiceType: method of your NSMutableURLRequest object to set the network service type of the request. The service type should be set to NSURLNetworkServiceTypeVoIP.- CFReadStreamRef and CFWriteStreamRef
For Core Foundation streams, use the CFReadStreamSetProperty or CFWriteStreamSetProperty function to add the kCFStreamNetworkServiceType property to the stream. The value for this property should be set to kCFStreamNetworkServiceTypeVoIP.
Is it possible in any way to set the kCFStreamNetworkServiceTypeVoIP type in socket as for CFReadStreamRef?
Currently a session is not retained when an MQTTClient object is reinitialized with the same client id and then connected to the broker. So for example, if I terminate my app, the session bound to the client object gets destroyed and I will no longer receive any offline messages.
Is there any workaround for this ?
It seems to be a problem with a pod spec when using cocoa pods 1.0.0.
Here is my pod file:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'MQTTDemo' do
pod 'MQTTKit', :git => 'https://github.com/mobile-web-messaging/MQTTKit.git'
end
Result:
pod install
Analysing dependencies
Pre-downloading: `MQTTKit` from `https://github.com/mobile-web-messaging/MQTTKit.git`
[!] Unable to find a specification for 'MQTTKit'.
[!] Unable to load a podspec from `MQTTKit.podspec`, skipping:
Pod::DSLError
@jmesnil, I have looked over the source code of this lib and I can see that you don't explicitly limit the length of the clientId
. But in the mosquitto lib, it is limited to a 23 bit length.
Is there a reason why it is limited? Because with your lib I use a UUID for the clientId
and it does not seem to complain, but with the other lib I cannot use a UUID. I'm just curious what is actually happening, does the C lib do the shorten string if it is to long or what is actually happening? The only reason I ask is because I want to be consistent with the client ids on both sides (the server and the iOS client).
I tried to display the MQTT client status, by showing the value of "connected" Boolean.
What I notice when I close any network connection, the MQTTKit does not detect the connection interruption (I tried to close wifi, and I was observing "connected" bool changes).
I think some reachability checking code can be added to enhence the connection loss detection.
(If I play the same scenario with MQTTClient framework, it detect that MQTT connection is lost.)
Messages sent through when my app is connected come through fine. Messages sent when the recipient is disconnected send fine but when the recipient later connects I don't receive any of the offline messages. I'm using the app with an Android counterpart and this receives my offline messages fine so the sending doesn't seem to be where the issue lies. I'm connecting with clean session set to false and have tried subscribing again as well as just connecting without resubscribing. Any ideas what the problem could be?
I am using apollo broker and libmosquitto C library to connect with the broker. Whenever I try to publish any message to the broker, the following error message is recorded in logs in my brokers home directory.
Following is the code snippet that i have been using
void on_publish(struct mosquitto *mosq, void *userdata, int mid)
{
log_print("mqtt",1,"Inside publish callback");
}
int sendData_mqtt(char *address, char *port,char *url,char *data) {
int err;
char *clean_session = "true";
char *retain_flag = "true";
int port1 = atoi(port);
struct mosquitto *mosq;
mosq = mosquitto_new("Mqtt", clean_session, NULL);
mosquitto_publish_callback_set(mosq, on_publish);
mosquitto_username_pw_set(mosq,"admin","password");
err=mosquitto_connect(mosq, address, port1,60);
if(err != 0 ){
log_print("mqtt",1,"connect error= %s\n",mosquitto_strerror(err));
return -1;
}
mosquitto_publish(mosq, NULL, "Mqtt", strlen(data), data, 1, retain_flag);
mosquitto_loop_forever(mosq, -1, 1);
return 0;
}
The weird thing is when i use the above program independently, it works fine but currently some other function in some other file is calling senddata_mqtt and in that case it throws the error which I stated above. Please help me know what is going on here.
May I ask why is the self.connected
set to YES
when the method connectWithCompletionHandler:(void (^)(MQTTConnectionReturnCode code))completionHandler;
is called on line 212
in MQTTKit.m
?
I would expect that to only be set to true or false when a connection is made with the server or closed, not before is opened as it happens in this case. Or is that intended behaviour?
Anyway, great work and very useful 👍
hi, i work with mosca, the connection restart,i found mosquitto_loop_read with _mosquitto_packet_read
return MOSQ_ERR_CONN_LOST
Why is the MessageTandler callback in the MQTTMessage object's mid is always 0
Hi, I have a confused. When I connect MQTT failed, the completionHandler block execute repeatly with error code, because of MQTT attempt to reconnect?
Hi, I'm trying to use the library in a swift project via cocoa pods. I created a bridging header and added "#import <MQTTKit.h>". It fails to build giving messages like these:
../Pods/Headers/MQTTKit/MQTTKit.h:10: unknown type name 'NSUInteger'
..Pods/Headers/MQTTKit/MQTTKit.h:27: cannot find interface declaration for 'NSObject', superclass of 'MQTTMessage'
...
I'm using other cocoa pods libs+swift in other projects and its fine.
can someone confirm? Any ideas for a work around?
thanks
wish you can update MQTT3.1 to MQTT3.1.1. it,s help me a lot.
I've been testing the TLS_support
branch for a few days now, and it seems to work fine.
There seems to be an issue, however, when I try and connect more and one client via SSL. This how I connect:
-(void)loadClient {
NSString *clientId = [NSString stringWithFormat:@"Client-1"];
NSString *topic = @"r/hello";
MQTTClient *client = [[MQTTClient alloc]initWithClientId:clientId];
[client setHost:@"123.456.789.0"];
[client setPort:8883];
[client setUsername:@"<username>"];
[client setPassword:@"<pass>"];
[client setCafile:[[NSBundle mainBundle]pathForResource:@"ca" ofType:@"crt"]];
[client connectWithCompletionHandler:^(MQTTConnectionReturnCode code) {
if (code == ConnectionAccepted) {
NSLog(@"connection accepted");
[client subscribe:topic withQos:AtLeastOnce completionHandler:^(NSArray *grantedQos) {
NSLog(@"Listening");
}];
}
}];
}
However, I get the following error:
0x10a551f89: movdqu 0x30(%r9), %xmm3 EXC_BAD_ACCESS(code=2)
I've had no luck debugging this.
Right now there are https://github.com/mobile-web-messaging/MQTTKit and https://github.com/jmesnil/MQTTKit.
Both master branches of those repositories are the same and the later one is used by the podspec, the first one seems to be historically the original.
So to which repo should we contribute pull requests?
How can i subscribe to multiple topic ?
When the timeout to reconnect, prompts the clientid is connected, return to the state of “ConnectionRefusedIdentiferRejected”
My code is as follows
self.client = [[MQTTClient alloc] initWithClientId:clientID cleanSession:YES];
[self.client connectToHost:kMQTTServerHost completionHandler:^(MQTTConnectionReturnCode code) { SYLog(@"client is connected with id %@", clientID);
if (code == ConnectionAccepted) {
SYLog(@"did connect...");
// The client is connected when this completion handler is called
SYLog(@"client is connected with id %@", clientID);
// Subscribe to the topic
[weakself.client subscribe:[NSString stringWithFormat:@"%@_%@", kTopic, usercount.enterprise_code] withCompletionHandler:^(NSArray *grantedQos) {
// The client is effectively subscribed to the topic when this completion handler is called
SYLog(@"subscribed to topic %@", [NSString stringWithFormat:@"%@_%@", kTopic, usercount.enterprise_code]);
BOOL res = [weakself.client enableBackgrounding];
if (!res) {
SYLog(@"Failed to enable background socket...");
}
}];
} else {
SYLog(@"Failed to connect to server...");
}
}];
[application setKeepAliveTimeout:600 handler:^{
SYLog(@"timeout handler activited...");
[weakself.client reconnect];
}];
In the time_mosq.c file ,line 88 , You should change "sec = (ticks/1000000000)(tb.numer/tb.denom);" to "sec = (ticks(tb.numer/tb.denom)/1000000000);"
Otherwise , when you set keepLive to 5 second ,MQTTKit keep reconnected to server
Is it possible to check all low level callbacks or can you give some example for low level call backs .
It would be really helpful if you respond on this.
Hey,
is it possible that the call for mosquitto_loop_forever(mosq, -1, 1);
is missing in (void) reconnect
?
If the client has a connection and you disconnect from it manually you could try to reconnect using the same client. But this wont work unless you add the call for
mosquitto_loop_forever(mosq, -1, 1);`.
Please see what I mean.
In MQTTKit.m change from:
- (void) reconnect {
mosquitto_reconnect(mosq);
}
to:
- (void) reconnect {
mosquitto_reconnect(mosq);
dispatch_async(self.queue, ^{
LogDebug(@"start mosquitto loop on %@", self.queue);
mosquitto_loop_forever(mosq, -1, 1);
LogDebug(@"end mosquitto loop on %@", self.queue);
});
}
With this change the client gets messages again and everything seems to work just fine again. Or am I missing some details?
How can I specify connect options (like client username, password)?
[client connectToHost
doesnt seem to provide that..
'read_handle.h' file not found with include; use "quotes" instead
Hi,
I am trying to use the MQTTKit framework in my Swift project. I was able to connect to my server and subscribe to a topic using the: "connectToHost:(NSString*)host completionHandler:" and "subscribe(NSString *)topic withCompletionHandler:" methods respectively; however, I was not able to
set a message handler as explained in the github doc here: https://github.com/jmesnil/MQTTKit#subscribe-to-a-topic-and-receive-messages.
Basically I don't see the "setMessageHandler:" method in the library.
Thanks,
Teddy
Dear All,
I have tried to include this library to an Apple TV project and got the following message:
Target 'Pods-TVApp' of project 'Pods' was rejected as an implicit dependency for 'libPods-TVApp.a' because it doesn't contain platform 'appletvsimulator' in its SUPPORTED_PLATFORMS 'iphonesimulator, iphoneos'
And I get this too:
ld: library not found for -lMQTTKit
This is my pod file:
# platform :ios, '6.0'
pod 'MQTTKit', :git => 'https://github.com/jmesnil/MQTTKit.git'
target 'iPhoneAppTest' do
end
target 'TVApp’ do
pod 'MQTTKit', :git => 'https://github.com/jmesnil/MQTTKit.git'
end
Any suggestion?
I have given the mqtt client a unique clientId, and the client connect to my sever successfully.After setting up the messageHandler, I can receive message from others..However, when I lock the screen, the client disconnect. And the messageHandler is invalid, so I can't received the offline message.. I have noticed that the MQTT Client have a property keepAlive, but it doesn't work for me..Any idea?
I use old version MQTTKit before, and recently update to the latest version. And I can't find connected property. How can I know Client connect status?
I can see that both publishString
and publishData
publish NSData
to the MQTT server. I have a small issue, I'm not sure if it is related to this lib though.
I'm using mosquitto in ruby, but when I subscribe and read the message it looks very funny, I almost cannot identify anything from what I actually publish:
bplist00RST$topX$objectsX$versionY$archiver�Troot��
!"#$%&'/;<=>JKLMU$null�
V$classZNS.objects����
��
WNS.keys��� �
�
�����UmajorUminor]proximityUUIDYtimestamp_$B9407F30-F5F8-466E-AFF9-25556B57FE6D_1400338443.678084�()*.X$classesZ$classname�+,-_NSMutableDictionary\NSDictionaryXNSObject_NSMutableDictionary�
��� 06�234��
�����_$B9407F30-F5F8-466E-AFF9-25556B57FE6D_1400338443.678005�
?E�ABC�����
�����_$B9407F30-F5F8-466E-AFF9-25556B57FE6D_1400338443.678049�()NQ�OP-\NSMutableSetUNSSet\NSMutableSet��_NSKeyedArchive(25:<TZ_fqswy{}��������������������
$(>KTjqvxz|~����������������������*/3@FSXTj
Is there anything I can do on the iOS end? Or is it on the other end where I read the data?
I too am trying to use the MQTTKit in a Swift application. Your example show this Obj-C code to create a message handler:
// define the handler that will be called when MQTT messages are received by the client
[self.client setMessageHandler:^(MQTTMessage *message) {
NSString *text = [message.payloadString];
NSLog(@"received message %@", text);
}];
I've attempted to translate it into the following Swift code:
self.client.messageHandler = { (message: MQTTMessage) -> Void in
// Do something here
}
but I get a compile error say that I can't assign a value of type (MQTTMessage) -> void to a value of MQTTMessageHandler. How do I resolve this issue?
I tried to see the MQTTExample in action. It is not working for me
The code for connecting to client
[self.client connectToHost:@"iot.eclipse.org"
completionHandler:^(MQTTConnectionReturnCode code) {
if (code == ConnectionAccepted) {
// when the client is connected, subscribe to the topic to receive message.
[self.client subscribe:@"/MQTTKit/example"
withCompletionHandler:nil];
}
}];
never gets a callback to the completion handler, so it does not go inside if / else (if i write one).
Any ideas what might be wrong or anything which i am missing.
static void on_disconnect(struct mosquitto *mosq, void *obj, int rc)
{
MQTTClient* client = (__bridge MQTTClient*)obj;
LogDebug(@"[%@] on_disconnect rc = %d", client.clientID, rc);
[client.publishHandlers removeAllObjects];
[client.subscriptionHandlers removeAllObjects];
[client.unsubscriptionHandlers removeAllObjects];
client.connected = NO;
if (client.disconnectionHandler) {
client.disconnectionHandler(rc);
}
}
Inside on_disconnect method, remove all the callbacks including publishHandlers, subscriptionHandlers, and unsubscriptionHandlers.
If the publish qos is AtLeastOnce or ExactlyOnce, remove the publishHandlers on disconnect seems not making sense.
The MQTTKit client is only notified of its disconnection from its disconnectWithCompletionHandler: method.
If the disconnection is unplanned (e.g. no pong from the server of the socket is closed), the client is never informed of the disconnection.
libmosquitto needs to be compiled with
WITH_THREADING=1
otherwise the pthread mutexes get stubbed out and there is a race condition between the mosquitto_loop_forever thread and the thread where you send new packets...
(Hope i didn't overlook it's already fixed...)
if i want to use a custome certificate, the mqttkit can support the tls/ssl?
Does the Objective-C implementation of the mosquito lib support TLS connections?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.