You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
6.5 KiB
185 lines
6.5 KiB
// |
|
// MyMQTT.m |
|
// myWear |
|
// |
|
// Created by xTT on 2017/2/24. |
|
// Copyright © 2017年 xTT. All rights reserved. |
|
// |
|
|
|
#import "MyMQTT.h" |
|
#import "User.h" |
|
|
|
@interface MyMQTT(){ |
|
NSMutableArray *mqttMsgArr; |
|
} |
|
|
|
@end |
|
|
|
@implementation MyMQTT |
|
|
|
+ (instancetype)sharedClient |
|
{ |
|
static MyMQTT *client = nil; |
|
static dispatch_once_t onceToken; |
|
dispatch_once(&onceToken, ^{ |
|
client = [[MyMQTT alloc] init]; |
|
[client.manager connectToLast]; |
|
}); |
|
return client; |
|
} |
|
|
|
- (MQTTSessionManager *)manager{ |
|
if (!_manager) { |
|
mqttMsgArr = [[NSMutableArray alloc] init]; |
|
|
|
_manager = [[MQTTSessionManager alloc] init]; |
|
_manager.delegate = self; |
|
[self connectMqtt]; |
|
|
|
[_manager addObserver:self |
|
forKeyPath:@"state" |
|
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew |
|
context:nil]; |
|
} |
|
return _manager; |
|
} |
|
|
|
- (void)connectMqtt{ |
|
if (cUser.openid.length > 0 && |
|
(_manager.state == MQTTSessionManagerStateClosed || _manager.state == MQTTSessionManagerStateClosing || _manager.state == MQTTSessionManagerStateStarting)) { |
|
NSString *clientId = [NSString stringWithFormat:@"%@@@@%@",self.mqttSettings[@"groupId"], |
|
[[User currentUser].openid substringToIndex:13]]; |
|
|
|
[_manager connectTo:self.mqttSettings[@"host"] |
|
port:[self.mqttSettings[@"port"] intValue] |
|
tls:[self.mqttSettings[@"tls"] boolValue] |
|
keepalive:60 //心跳间隔不得大于120s |
|
clean:true |
|
auth:true |
|
user:self.mqttSettings[@"accessKey"] |
|
pass:self.mqttSettings[@"passWord"] |
|
will:false |
|
willTopic:nil |
|
willMsg:nil |
|
willQos:MQTTQosLevelAtLeastOnce |
|
willRetainFlag:FALSE |
|
withClientId:clientId |
|
securityPolicy:nil |
|
certificates:nil |
|
protocolLevel:MQTTProtocolVersion31]; |
|
} |
|
} |
|
|
|
- (void)setSubscriptions:(id)obj{ |
|
NSMutableDictionary *dic = [NSMutableDictionary dictionary]; |
|
if (cUser.openid.length > 0) { |
|
NSString *userTopic = [NSString stringWithFormat:@"%@/user/%@",self.mqttSettings[@"rootTopic"],cUser.openid]; |
|
|
|
dic = [NSMutableDictionary dictionaryWithDictionary:@{userTopic:@(MQTTQosLevelAtLeastOnce)}]; |
|
} |
|
|
|
if ([obj isKindOfClass:[Circle class]]) { |
|
NSString *chatTopic = [NSString stringWithFormat:@"%@/chatGroup/%@",self.mqttSettings[@"rootTopic"],[obj groupid]]; |
|
[dic addEntriesFromDictionary:@{chatTopic:@(MQTTQosLevelAtLeastOnce)}]; |
|
} |
|
_manager.subscriptions = dic; |
|
if (cUser.openid.length > 0) { |
|
[self connectMqtt]; |
|
}else{ |
|
[_manager disconnect]; |
|
} |
|
} |
|
|
|
|
|
- (NSDictionary *)mqttSettings{ |
|
if (!_mqttSettings) { |
|
NSURL *bundleURL = [[NSBundle mainBundle] bundleURL]; |
|
NSURL *mqttPlistUrl = [bundleURL URLByAppendingPathComponent:@"mqtt.plist"]; |
|
_mqttSettings = [NSDictionary dictionaryWithContentsOfURL:mqttPlistUrl]; |
|
} |
|
return _mqttSettings; |
|
} |
|
|
|
- (void)sendMsg:(NSString *)msg circle:(Circle *) circle{ |
|
NSString *chatTopic = [NSString stringWithFormat:@"%@/chatGroup/%@",self.mqttSettings[@"rootTopic"],[circle groupid]]; |
|
[self.manager sendData:[msg dataUsingEncoding:NSUTF8StringEncoding] |
|
topic:[NSString stringWithFormat:@"%@/%@",chatTopic,@"IOS"]//此处设置多级子topic |
|
qos:MQTTQosLevelAtLeastOnce |
|
retain:FALSE]; |
|
} |
|
|
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { |
|
switch (self.manager.state) { |
|
case MQTTSessionManagerStateClosed: |
|
// self.status.text = @"closed"; |
|
// self.disconnect.enabled = false; |
|
// self.connect.enabled = false; |
|
break; |
|
case MQTTSessionManagerStateClosing: |
|
// self.status.text = @"closing"; |
|
// self.disconnect.enabled = false; |
|
// self.connect.enabled = false; |
|
break; |
|
case MQTTSessionManagerStateConnected: |
|
// self.status.text = [NSString stringWithFormat:@"connected as %@", |
|
// self.clientId]; |
|
// self.disconnect.enabled = true; |
|
// self.connect.enabled = false; |
|
break; |
|
case MQTTSessionManagerStateConnecting: |
|
// self.status.text = @"connecting"; |
|
// self.disconnect.enabled = false; |
|
// self.connect.enabled = false; |
|
break; |
|
case MQTTSessionManagerStateError: |
|
// self.status.text = @"error"; |
|
// self.disconnect.enabled = false; |
|
// self.connect.enabled = false; |
|
break; |
|
case MQTTSessionManagerStateStarting: |
|
default: |
|
// self.status.text = @"not connected"; |
|
// self.disconnect.enabled = false; |
|
// self.connect.enabled = true; |
|
break; |
|
} |
|
} |
|
|
|
/* |
|
* MQTTSessionManagerDelegate |
|
*/ |
|
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained { |
|
/* |
|
* MQTTClient: process received message |
|
*/ |
|
NSString *dataString = [[NSString alloc] initWithData:data |
|
encoding:NSUTF8StringEncoding]; |
|
|
|
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data |
|
options:NSJSONReadingMutableLeaves |
|
error:nil]; |
|
|
|
xLog(@"mqtt %d %@ %@",retained,topic,dic); |
|
|
|
if (dic && ![mqttMsgArr containsObject:dataString]) { |
|
[mqttMsgArr addObject:dataString]; |
|
[[NSNotificationCenter defaultCenter] postNotificationName:dic[@"type"] |
|
object:dic]; |
|
|
|
if (mqttMsgArr.count > 50) { |
|
[mqttMsgArr removeObjectAtIndex:0]; |
|
} |
|
} |
|
} |
|
|
|
- (NSString *)macSignWithText:(NSString *)text secretKey:(NSString *)secretKey |
|
{ |
|
NSData *saltData = [secretKey dataUsingEncoding:NSUTF8StringEncoding]; |
|
NSData *paramData = [text dataUsingEncoding:NSUTF8StringEncoding]; |
|
NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH ]; |
|
CCHmac(kCCHmacAlgSHA1, saltData.bytes, saltData.length, paramData.bytes, paramData.length, hash.mutableBytes); |
|
NSString *base64Hash = [hash base64EncodedStringWithOptions:0]; |
|
|
|
return base64Hash; |
|
} |
|
@end
|
|
|