iOS mqtt & protobuf(三) 合體

protobuf&Mqtt

1.簡(jiǎn)單來(lái)說(shuō)就是將Data扔mqtt诗芜,然后發(fā)送出去就行了!!!

成果展示

啟動(dòng)服務(wù)器

image.png

Demo演示

mqttGIF.gif

具體代碼

CocoaPods導(dǎo)入需要的SDK

1.Protobuf是protobuf的依賴庫(kù)
2.MQTTClient是一個(gè)開源的Mqtt庫(kù)彼妻,包括鏈接噪漾,訂閱,發(fā)布消息馏慨,接收消息等等(只要站在巨人肩膀上開發(fā)就好了展东,除非你是研發(fā)型的公司寄雀,需要自己去研發(fā)一套協(xié)議或者一套新的框架)。
pod 'Protobuf'
pod 'MQTTClient'
3.創(chuàng)建一個(gè)通訊管理類(管理鏈接奶稠,中斷鏈接俯艰,接收和發(fā)送消息)

注意:這里僅作為展示,不做過(guò)多的處理锌订,需要做成一個(gè)完整的項(xiàng)目還需要更多的東西

//
//  MqttManager.h
//  MQTTDemo
//
//  Created by Avalanching on 2019/3/27.
//  Copyright ? 2019 Avalanching. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <MQTTClient/MQTTClient.h>
#import "MQTTUserInfo.h"
#import "MqttMessageBody.pbobjc.h"

typedef NS_ENUM(NSInteger, MQTTConnectionCode) {
    MQTTConnectionCodeDidConnection
};

@protocol AVAMqttManagerDelegate <NSObject>

/**
 @method sendMessageCallBackWithBool:message:
 @abstrac 發(fā)送回調(diào)
 @discussion 回調(diào)結(jié)果是否發(fā)送成功了
 @param flag 發(fā)送結(jié)果
 @param body 發(fā)送的信息
 */
- (void)sendMessageCallBackWithBool:(BOOL)flag message:(MqttMessageBody *)body;

/**
 @method newMessageArrival:
 @abstrac 收到新的信息
 @discussion 收到信息的回調(diào)
 @param message 發(fā)送的信息
 */
- (void)newMessageArrival:(MqttMessageBody *)message;

@end

@interface MqttManager : NSObject

// 登陸信息
@property (nonatomic, strong, readonly) MQTTUserInfo * userinfo;

// 終端連接回調(diào)
@property (nonatomic, copy, readonly) BOOL (^interruptblock)(MQTTConnectionCode code, NSString *msg);

/**
 @method shareManager
 @abstrac 獲取一個(gè)管理者單例對(duì)象
 @discussion 用來(lái)管理MQTT的綁定竹握,訂閱,鏈接辆飘,中斷啦辐,接收,發(fā)送
 @result MqttManager / NULL (instancetype 僅返回值蜈项,告訴編譯器不報(bào)異常)
 */
+ (instancetype)shareManager;

/**
 @method loginWithMQTTUserInfo:
 @abstrac 用戶登陸MQTT服務(wù)器
 @discussion 必須登陸以后才可以登陸
 @param userinfo block
 */
- (void)loginWithMQTTUserInfo:(MQTTUserInfo *)userinfo complete:(BOOL(^)(MQTTConnectionCode code, NSString *msg))block;

/**
 @method addSubscriptionWithTheme:
 @abstrac 訂閱主題
 @discussion 默認(rèn)為@"$SYS/IM"
 @param theme NSString *
 */
- (BOOL)addSubscriptionWithTheme:(NSString *)theme;

/**
 @method disConnection
 @abstrac 中斷鏈接
 */
- (void)disConnection;

/**
 @method sendMessageWithData:
 @abstrac 發(fā)送消息
 @param data NSString
 */
- (void)sendMessageWithData:(NSData *)data;

/**
 @method isSendWithMessageBody:
 @abstrac 判斷是不是發(fā)送者
 @discussion 傳入一個(gè)消息對(duì)象
 @param body MqttMessageBody*
 @result BOOL (NO 接收者/YES 發(fā)送者)
 */
- (BOOL)isSendWithMessageBody:(MqttMessageBody *)body;


/**
 @method addDelegatesWithObject:
 @abstrac 添加一個(gè)代理對(duì)象
 @discussion 傳入一個(gè)代理對(duì)象
 @param delegate id<AVAMqttManagerDelegate> 代理對(duì)象
 */
- (void)addDelegatesWithObject:(id<AVAMqttManagerDelegate>)delegate;

/**
 @method removeDelegateObject:
 @abstrac 刪除一個(gè)代理對(duì)象
 @discussion 傳入一個(gè)代理對(duì)象
 @param delegate id<AVAMqttManagerDelegate> 代理對(duì)象
 */
- (void)removeDelegateObject:(id<AVAMqttManagerDelegate>)delegate;

@end

/** 登陸方法
 *   - (void)loginWithMQTTUserInfo:(MQTTUserInfo *)userinfo
 *  complete:(BOOL(^)(MQTTConnectionCode code, NSString *msg))block;
 */
在使用MQTTClient:

1.需要?jiǎng)?chuàng)建一個(gè)MQTTSession對(duì)象芹关,這是管理鏈接的上下文,控制鏈接紧卒,中斷充边,發(fā)送,消息,訂閱和驗(yàn)證等等浇冰。
MQTTSession是MQTTClient的core類的上層封裝贬媒,相當(dāng)于一個(gè)外部接口類,作者給其定義了多種方法肘习。

2.設(shè)置一個(gè)MQTTSession的Delegate际乘,用來(lái)處理鏈接相關(guān)的回調(diào)。

3.定義自己的通訊格式漂佩,上一章舉例了一個(gè)MessageBody對(duì)象(正常開發(fā)需要更多字段去標(biāo)識(shí)一條消息)

注意

1.MQTTSession提供了兩類型的構(gòu)建方法
a.常規(guī)方法

+ (id)alloc;
- (id)init;

b.類別中添加的方法

- (MQTTSession *)initWithClientId:(NSString *)clientId
                         userName:(NSString *)userName
                         password:(NSString *)password
                        keepAlive:(UInt16)keepAliveInterval
                   connectMessage:(MQTTMessage *)theConnectMessage
                     cleanSession:(BOOL)cleanSessionFlag
                             will:(BOOL)willFlag
                        willTopic:(NSString *)willTopic
                          willMsg:(NSData *)willMsg
                          willQoS:(MQTTQosLevel)willQoS
                   willRetainFlag:(BOOL)willRetainFlag
                    protocolLevel:(UInt8)protocolLevel
                            queue:(dispatch_queue_t)queue
                   securityPolicy:(MQTTSSLSecurityPolicy *) securityPolicy
                     certificates:(NSArray *)certificates;

雖然作者很貼心對(duì)參數(shù)進(jìn)行了解釋脖含,但我還是要在說(shuō)一下,避免篇幅過(guò)短成了水文

ClientId:客戶機(jī)標(biāo)識(shí)符向服務(wù)器標(biāo)識(shí)客戶機(jī)投蝉。如果為零养葵,則生成隨機(jī)的clientID

userName:用于身份驗(yàn)證的用戶名(或ID)的nsstring對(duì)象〈窭拢可能是零关拒。

password:用戶密碼的nsstring對(duì)象。如果用戶名為零庸娱,密碼也必須為零着绊。

keepAlive:是以秒為單位的時(shí)間間隔。mqttclient確保發(fā)送的控制包之間的間隔不超過(guò)keep-alive值熟尉。在沒有發(fā)送任何其他控制包的情況下归露,客戶機(jī)發(fā)送一個(gè)pingreq包,設(shè)置心跳間隔不得大于120s

connectMessage:鏈接發(fā)送的消息

cleanSession:指定服務(wù)器是否應(yīng)放棄以前的會(huì)話信息斤儿。

will:will標(biāo)志設(shè)置為yes剧包,則表示當(dāng)服務(wù)器檢測(cè)到客戶機(jī)由于任何原因(而非客戶機(jī)主動(dòng)斷開數(shù)據(jù)包)斷開連接時(shí),服務(wù)器必須發(fā)布will消息往果。異常退出

willTopic:如果上一項(xiàng)will標(biāo)志設(shè)置為yes玄捕,will主題是一個(gè)字符串,否則為nil棚放。

willMsg:如果will標(biāo)志設(shè)置為yes枚粘,則必須指定will消息,否則為nil飘蚯。

willQoS:指定發(fā)布will消息時(shí)要使用的qos級(jí)別馍迄。如果will標(biāo)志設(shè)置為no,那么will qos必須設(shè)置為0局骤。

willRetainFlag:指示服務(wù)器是否應(yīng)使用retainFlag發(fā)布will消息攀圈。如果will標(biāo)志設(shè)置為no,則will retain標(biāo)志必須設(shè)置為no峦甩。如果will標(biāo)志設(shè)置為yes:如果will retain設(shè)置為no赘来,服務(wù)器必須將will消息發(fā)布為非保留發(fā)布[mqtt-3.1.2-14]现喳。如果will retain設(shè)置為yes,服務(wù)器必須將will消息發(fā)布為保留發(fā)布[mqtt-3.1.2-15]犬辰。
     
protocolLevel:指定要使用的協(xié)議嗦篱。協(xié)議版本3.1.1的協(xié)議級(jí)別字段的值為4。版本3.1的值為3幌缝。
     
queue:安排流的隊(duì)列進(jìn)行排隊(duì)

securityPolicy:安全策略用于評(píng)估安全連接的服務(wù)器信任的安全策略灸促。

certificates:提供的描述回復(fù)需要客戶端證書的服務(wù)器的身份證書。

我采用的創(chuàng)建方式

// MQTT配置類涵卵,設(shè)置訪問地址和端口號(hào)
// MQTTCFSocketTransport 安全驗(yàn)證管理
MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init];
transport.host = HOST;
transport.port = PORT;

self.session = [[MQTTSession alloc] init];
self.session.transport = transport;
self.session.delegate = self;    

// 設(shè)置超時(shí)
[self.session setDupTimeout:30];
// 設(shè)置賬號(hào)密碼
[self.session setUserName:userinfo.username];
[self.session setPassword:userinfo.password];
[self.session subscribeToTopic:DefaultsTheme atLevel:MQTTQosLevelAtMostOnce];
驗(yàn)證管理
- (MQTTSSLSecurityPolicy *)customSecurityPolicy {
    
    MQTTSSLSecurityPolicy *securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeNone];
    
    // 是否使用驗(yàn)證
    securityPolicy.allowInvalidCertificates = YES;
    securityPolicy.validatesCertificateChain = YES;
    securityPolicy.validatesDomainName = NO;
    // 需要證書請(qǐng)?jiān)O(shè)置這個(gè)
    // securityPolicy.pinnedCertificates
    return securityPolicy;
}
如何查看狀態(tài)

這里MQTTClient很貼心為我們提供了很多回調(diào)浴栽,包括鏈接狀態(tài)的回調(diào)

/** for mqttio-OBJC backward compatibility
 @param session the MQTTSession reporting the event
 @param eventCode the code of the event
 */
- (void)session:(MQTTSession*)session handleEvent:(MQTTSessionEvent)eventCode;

/** gets called when a connection has been successfully established
 @param session the MQTTSession reporting the connect
 
 */
- (void)connected:(MQTTSession *)session;

/** gets called when a connection has been successfully established
 @param session the MQTTSession reporting the connect
 @param sessionPresent represents the Session Present flag sent by the broker
 
 */
- (void)connected:(MQTTSession *)session sessionPresent:(BOOL)sessionPresent;

/** gets called when a connection has been refused
 @param session the MQTTSession reporting the refusal
 @param error an optional additional error object with additional information
 */
- (void)connectionRefused:(MQTTSession *)session error:(NSError *)error;

/** gets called when a connection has been closed
 @param session the MQTTSession reporting the close

 */
- (void)connectionClosed:(MQTTSession *)session;

/** gets called when a connection error happened
 @param session the MQTTSession reporting the connect error
 @param error an optional additional error object with additional information
 */
- (void)connectionError:(MQTTSession *)session error:(NSError *)error;

這里為了快速用了KVC,去觀察了“status”屬性

// 添加監(jiān)聽狀態(tài)觀察者
[self.session addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];

// 監(jiān)聽當(dāng)前連接狀態(tài)
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    MQTTSessionStatus eventCode = self.session.status;
    switch (eventCode) {
        case MQTTSessionStatusCreated:
            NSLog(@"%s\n創(chuàng)建鏈接:%ld", __func__, (long)eventCode);
            break;
        case MQTTSessionStatusConnecting:
            NSLog(@"%s\n鏈接中:%ld", __func__, (long)eventCode);
            break;
        case MQTTSessionStatusConnected:
            NSLog(@"%s\n已經(jīng)鏈接:%ld", __func__, (long)eventCode);
            if (_interruptblock) {
                self.interruptblock(MQTTConnectionCodeDidConnection, @"已經(jīng)鏈接了");
            }
            break;
        case MQTTSessionStatusDisconnecting:
            NSLog(@"%s\n正在斷開鏈接:%ld", __func__, (long)eventCode);
            break;
        case MQTTSessionStatusClosed:
            NSLog(@"%s\n關(guān)閉鏈接:%ld", __func__, (long)eventCode);
            if (self.isClose) {
                return;
            } else {
                [self.session connect];
            }
        default:
            NSLog(@"%s\n鏈接錯(cuò)誤:%ld", __func__, (long)eventCode);
            break;
    }
}

Demo路徑:https://github.com/Avanlanching/MQTTDemo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末轿偎,一起剝皮案震驚了整個(gè)濱河市典鸡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌坏晦,老刑警劉巖萝玷,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異英遭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)亦渗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門挖诸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人法精,你說(shuō)我怎么就攤上這事多律。” “怎么了搂蜓?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵狼荞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我帮碰,道長(zhǎng)相味,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任殉挽,我火速辦了婚禮丰涉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘斯碌。我一直安慰自己一死,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布傻唾。 她就那樣靜靜地躺著投慈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伪煤,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天加袋,我揣著相機(jī)與錄音,去河邊找鬼带族。 笑死锁荔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蝙砌。 我是一名探鬼主播阳堕,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼择克!你這毒婦竟也來(lái)了恬总?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肚邢,失蹤者是張志新(化名)和其女友劉穎壹堰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骡湖,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贱纠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了响蕴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谆焊。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖浦夷,靈堂內(nèi)的尸體忽然破棺而出辖试,到底是詐尸還是另有隱情,我是刑警寧澤劈狐,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布罐孝,位于F島的核電站,受9級(jí)特大地震影響肥缔,放射性物質(zhì)發(fā)生泄漏莲兢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一续膳、第九天 我趴在偏房一處隱蔽的房頂上張望怒见。 院中可真熱鬧,春花似錦姑宽、人聲如沸遣耍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舵变。三九已至酣溃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纪隙,已是汗流浹背赊豌。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绵咱,地道東北人碘饼。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像悲伶,于是被迫代替她去往敵國(guó)和親艾恼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,767評(píng)論 0 15
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)麸锉、插件钠绍、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 文章首次整理發(fā)布自個(gè)人博客:一之筆 -> iOS MQTT 使用詳解 引言 之前我整理過(guò)關(guān)于RabbitMQ在iO...
    阿木攝影閱讀 4,392評(píng)論 4 12
  • 早在一個(gè)月之前就定好了機(jī)票和住宿,只因?yàn)槲覀兌枷矚g大海花沉,想要去吹吹海風(fēng)柳爽,聽聽海浪,看看日出日暮碱屁,潮漲潮落磷脯。這是我第...
    當(dāng)下的航子閱讀 459評(píng)論 7 8
  • 筆者在三十多年的人力資源管理教學(xué)赵誓、研究、咨詢實(shí)踐中,總結(jié)提煉并一直倡導(dǎo)的人力資源管理理念與思維主要有二十句話: 1...
    仁道中年的大叔閱讀 725評(píng)論 0 0