XMPP協議實現即時通信底層書寫 (二)-- IOS XMPPFramework Demo+分析

我但願,This is a new day! git

在看代碼以前,我認爲你仍是應該先整理一下心情,來聽我說幾句:github

首先,我但願你是在早上邊看這篇blog,而後一邊開始動手操做。假設你僅僅是看blog而不去本身對照項目,做用不是很是大。數據庫

一日之計在於晨,因此懷着一顆對技術渴望,激動的,亢奮的心情去學習。你才幹有所得。嗯,就拿鄙人當時作項目來講,天天早上起來的第一件事情,就是研究XMPPFramework做者的代碼,依照模塊來分析和模仿書寫。睡覺的時候還在思考,分析,總結...session


固然我並不是說每個Dev 都要向我這樣,僅僅是但願你能保持一顆積極向上的心態去對待技術,對待你的工做。架構

that's all。app


ResourceURL:https://github.com/robbiehanson/XMPPFramework  (假設你還在維護你現有的基於XMPP的產品,那麼你需要sometimes 去查看。原做者是否fix 一些bug)dom


IphoneXMPP Demosocket

1.AppDelegate.mide

a.大概看下頭文件,ok。別跳轉深刻看了。如下我會教高速的看。See this methodpost


有幾個地方需要注意:

  1)DDLog 用於不用不強求。鄙人喜歡乾淨清爽的控制檯。因此就沒用這玩意。因爲我並不是很是依賴全部打log。而是斷點控制檯po XXX方法,實時性找出問題修復bug

  2)配置XML Stream 流 ,給你的長鏈接裏面添加各類 buff,各類裝備,各類屬性。ok,不開玩笑了:),這個配置很是重要,它決定了你的app需要支持哪些xmpp服務。決定了原做者(羅賓遜)哪些代碼功能模塊是不需要生效的

  3)啓動鏈接,固然相應的也有一個cancel connect


b 設置你的 XML Stream ,開啓哪些功能

- (void)setupStream
{
	NSAssert(xmppStream == nil, @"Method setupStream invoked multiple times");
	
	// Setup xmpp stream
	// 
	// The XMPPStream is the base class for all activity.
	// Everything else plugs into the xmppStream, such as modules/extensions and delegates.

	xmppStream = [[XMPPStream alloc] init];
	
	#if !TARGET_IPHONE_SIMULATOR
	{
		// Want xmpp to run in the background?
		// 
		// P.S. - The simulator doesn't support backgrounding yet.
		//        When you try to set the associated property on the simulator, it simply fails.
		//        And when you background an app on the simulator,
		//        it just queues network traffic til the app is foregrounded again.
		//        We are patiently waiting for a fix from Apple.
		//        If you do enableBackgroundingOnSocket on the simulator,
		//        you will simply see an error message from the xmpp stack when it fails to set the property.
		
		<span style="color:#66ff99;">xmppStream.enableBackgroundingOnSocket = YES;</span>
	}
	#endif
	
	// Setup reconnect
	// 
	// The XMPPReconnect module monitors for "accidental disconnections" and
	// automatically reconnects the stream for you.
	// There's a bunch more information in the XMPPReconnect header file.
	
	xmppReconnect = [[XMPPReconnect alloc] init];
	
	// Setup roster
	// 
	// The XMPPRoster handles the xmpp protocol stuff related to the roster.
	// The storage for the roster is abstracted.
	// So you can use any storage mechanism you want.
	// You can store it all in memory, or use core data and store it on disk, or use core data with an in-memory store,
	// or setup your own using raw SQLite, or create your own storage mechanism.
	// You can do it however you like! It's your application.
	// But you do need to provide the roster with some storage facility.
	
	xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
//	xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] initWithInMemoryStore];
	
	xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];
	
	xmppRoster.autoFetchRoster = YES;
	xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;
	
	// Setup vCard support
	// 
	// The vCard Avatar module works in conjuction with the standard vCard Temp module to download user avatars.
	// The XMPPRoster will automatically integrate with XMPPvCardAvatarModule to cache roster photos in the roster.
	
	xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
	xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
	
	xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule];</span>
	
	// Setup capabilities
	// 
	// The XMPPCapabilities module handles all the complex hashing of the caps protocol (XEP-0115).
	// Basically, when other clients broadcast their presence on the network
	// they include information about what capabilities their client supports (audio, video, file transfer, etc).
	// But as you can imagine, this list starts to get pretty big.
	// This is where the hashing stuff comes into play.
	// Most people running the same version of the same client are going to have the same list of capabilities.
	// So the protocol defines a standardized way to hash the list of capabilities.
	// Clients then broadcast the tiny hash instead of the big list.
	// The XMPPCapabilities protocol automatically handles figuring out what these hashes mean,
	// and also persistently storing the hashes so lookups aren't needed in the future.
	// 
	// Similarly to the roster, the storage of the module is abstracted.
	// You are strongly encouraged to persist caps information across sessions.
	// 
	// The XMPPCapabilitiesCoreDataStorage is an ideal solution.
	// It can also be shared amongst multiple streams to further reduce hash lookups.
	
	xmppCapabilitiesStorage = [XMPPCapabilitiesCoreDataStorage sharedInstance];
    xmppCapabilities = [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage];

    xmppCapabilities.autoFetchHashedCapabilities = YES;
    xmppCapabilities.autoFetchNonHashedCapabilities = NO;

	// Activate xmpp modules

	[xmppReconnect         activate:xmppStream];
	[xmppRoster            activate:xmppStream];
	[xmppvCardTempModule   activate:xmppStream];
	[xmppvCardAvatarModule activate:xmppStream];
	[xmppCapabilities      activate:xmppStream];

	// Add ourself as a delegate to anything we may be interested in

	[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
	[xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];

	// Optional:
	// 
	// Replace me with the proper domain and port.
	// The example below is setup for a typical google talk account.
	// 
	// If you don't supply a hostName, then it will be automatically resolved using the JID (below).
	// For example, if you supply a JID like 'user@quack.com/rsrc'
	// then the xmpp framework will follow the xmpp specification, and do a SRV lookup for quack.com.
	// 
	// If you don't specify a hostPort, then the default (5222) will be used.
	
//	[xmppStream setHostName:@"talk.google.com"];
//	[xmppStream setHostPort:5222];	
	

	// You may need to alter these settings depending on the server you're connecting to
	customCertEvaluation = YES;
}

ok,let's begin.

1)建立一個XML stream 對象。這貨是幹嗎的呢。

打個比喻:貨物運輸帶,上貨和下貨 都要靠這條帶子。

誰讓這條帶子動起來?

長鏈接

它就是個馬達。

那麼這裏面的貨是啥呢?3種貨:美版,港版,日版。偶爾帶點國行。

(*^__^*) 嘻嘻……。哈哈不開玩笑了。有三種貨:<iq> <p><message>,偶爾帶點其它標籤<a><r>什麼的。

索達斯內。~斯ko一!~是的,好厲害好棒噠!

~發現昨天看得RFC6121有點關係啦。~\(≧▽≦)/~啦啦啦

2)是否開啓後臺模式---NO。除非你有VOIP需要支持,否則後患無窮,現在github 上後臺issue另外一大堆沒解決的呢,反正呢很是複雜噠。我這菜逼就沒支持這貨

<span style="color:#66ff99;">xmppStream.enableBackgroundingOnSocket</span>

3)開啓重連機制(長鏈接必備。心跳啥的)

開啓roster(兩種形式:coreData存儲 or 開闢內存--暫時對象存儲)。本身主動獲取server上的roster數據?是否本身主動應答 已經存在訂閱出席消息的小夥伴的訂閱請求,也就是說是否本身主動過濾掉已經訂閱過的訂閱或者是已經造成訂閱關係的用戶請求啦(難點,後面章節細講)。開啓roster CoreDataStorage,也就是數據庫存CoreData儲技術。


開啓vCard(我的信息詳情) module,二次封裝vCard Module開啓,並且啓動 vcard相應的coreData 存儲技術

開啓capabilitie,和與之的存儲技術。這貨當初看了很久噠。但是現在真忘記了。

。。sorry,這塊需要找相應的XEP來進行腦補,只是貌似臨時用不到。就讓它默認吧。

原文連接傳送門

如下是 XMPPFramework的一個核心:multi delegate (做者獨有,膜拜!

~)

[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
	[xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];


對XML stream 進行加入一個Sub Delegate回調,在當前Class,在mainThread Queue中,

對roster 進行一個sub delegate回調,在當前Class,主線程隊列。

關於multi delegate 技術,建議好好看看裏面的詳細實現,不要求你會寫。大概的核心思想能看懂就成。會return BOOL YES or NO 就能夠。。。



btw1:鄙人對這個multi delegate再次膜拜,固然他寫的很是多東西,都是讓我膜拜的。。比方socket連接。

。。XML解析。DDLog。。。

反正好多,好了不說了。說多了都是淚,菜狗僅僅能仰望大神。。

btw2:刷刷刷兩個小時過去了,洗洗睡了,寫blog真心很是累。

btw3:server那個水?問你呢,大家環境配好了沒,我這邊要example測試鏈接了。快給個帳號和password。勞資效率就是這麼高。一天搞定主要的數據鏈接了。

btw4:經理,我這邊還算順利,約有小成,你看這鏈接界面,成了。儘管界面醜了點,但是能連上服務端了。真棒。

btw5:啪!你個傻蛋。別說這事demo。怎麼有你這樣的隊友。

btw6:下期預告<IOS XMPPFramework --IM底層架構設計+技術準備工做>

相關文章
相關標籤/搜索