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