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

//
// 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