(在設定以下這些東西,通常都是在AppDelegate中進行實作)
1. 首先,設定連線
其實設定連線步驟很簡單,只要設定JID就可以了,範例如下:
xmppStream.myJID = [XMPPJID jidWithString:@"tungtungtsai@gmail.com"];
xmppStream.myJID = [XMPPJID jidWithString:@"user@tungtungtsai.com"];
xmppStream.hostName = @"tungtungtsai.com";
xmppStream.myJID = [XMPPJID jidWithString:@"user@dev1.myCompany.com"];
xmppStream.hostName = @"192.168.2.27";
2. 添加代理(Delegates)
上一篇提到關於XMPPStream有些讓framework更具彈性、延展性、易開發的設計,而其一就是MulticastDelegate。由於xmpp framework需要支援很多的extensions,包含官方的和個人開發者所自己撰寫的plugin,所以傳統的代理模式(Delegate pattern)並不適合。因此,MulticastDelegate就可以讓你在你自己的extension中使用標準的delegate paradigm,並且允許多個classes去接收同一個delegate notification。這樣地好處是你不需要把你所有的xmpp handling code放進單一個class。
這裡簡單提一下:
在iOS開發中,主要有兩個callback systems,delegate和notification。Delegate很直覺也很簡單。使用者把自己設為delegate,然後就可以實作自己需要的delegate method。例如:
[worker setDelegate:self];
- (void)workerDidFinish:(Worker *)sender
{
}
- (void)worker:(Worker *)sender didFinishSubTask:(id)subtask inDuration:(NSTimeInterval)elapsed
{
}
- (BOOL)worker:(Worker *)sender shouldPerformSubTask:(id)subtask
{
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(workerDidFinish:)
name:WorkerDidFinishNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(workerDidFinishSubTask:)
name:WorkerDidFinishSubTaskNotification
object:nil];
- (void)workerDidFinish:(NSNotification *)notification
{
Worker *sender = [notification object];
}
- (void)workerDidFinishSubTask:(NSNotification *)notification
{
Worker *sender = [notification object];
id subtask = [[notification userInfo] objectForKey:@"subtask"];
NSTimeInterval elapsed = [[[notification userInfo] objectForKey"duration"] doubleValue];
}
有時候要從notification中的Dictionary取出參數的話,就要先知道他擁有哪些keys。另外,notification是不允許回傳變數的。因此簡單地對兩個callback機制的優缺點分析如下:
Delegate優點:
1. 易於註冊多個callback
2. 當有多個參數時較易於使用
3. 允許回傳變數
Delegate缺點:
1. 只能夠是單一delegate
Notification優點:
1. 可以多個物件註冊同一個notification
Notification缺點:
1. 註冊多個callback較複雜
2. 要從dictionary中拿到參數很麻煩(要知道正確的key)
3. 當需要回傳變數時就不能使用
所以,對於XMPP framework來說哪一個方式適用呢?對XMPP來說,xmpp framework需要能夠廣播給多個listeners。例如當你有個message進來,你需要同時廣播給聊天的視窗、歷史紀錄和推播系統等等。此外,xmpp framework需要易於延展。xmpp要能夠支持很多的XEP,所以要能在broadcast端與listener端易於使用。xmpp framework 需要選擇能支持回傳變數的方式,也需要能夠幫助維持 thread-safety,因為xmpp framework大量地使用平行化與多線程。
講完你就發現好像delegate和notification都不是最好的解決方法,因此xmpp就創了一個GCDMulticastDelegate class。你可以在任何時候把你自己新增/移除為XMPPStream的delegate。
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
...
[xmppStream removeDelegate:self];
簡單範例如下:
// Add myself as a delegate, and tell xmppStream to invoke my delegate methods on the main thread
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
// Then just implement whatever delegate methods you need like normal
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
...
}
就和傳統的代理模式差不多,但是你可以具體地說明thread-specific資訊。而如果你想要讓某些process離開主線程到背景執行也很容易,在iPhone中這種操作方式可以讓你的app維持良好的perfomance,範例如下:
// Handle most stuff on the main thread
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
// But do that one slow thing on a background queue so it doesn't slow down the UI anymore
[xmppStream addDelegate:bgProcessor delegateQueue:bgProcessorQueue];
3. 添加模組(Modules)
接下來就是要加入我們自己需要的extensions了,當然你也可以自己寫自己需要的extensions,這裡我們不會探討到底有哪些extensions,僅簡單列出一些,因為這裡最重要的是要學會加入模組。
XMPPReconnect - 當斷線時自動重新連線
XMPPRoster - 提供聯絡人功能
XMPPRoom - 提供聊天室,群聊功能
XMPPPubSub - 提供發布與訂閱功能
XMPPRoster - 提供聯絡人功能
XMPPRoom - 提供聊天室,群聊功能
XMPPPubSub - 提供發布與訂閱功能
現在我們來試著加入XMPPReconnect module到我們的xmpp stream吧!
xmppReconnect = [ [XMPPReconnect alloc] init];
// Optional configuration of xmppReconnect could go here.
// The defaults are fine for our purposes.
[xmppReconnect activate:xmppStream];
// You can also optionally add delegates to the module.
[xmppReconnect addDelegate:self delegateQueue:dispatch_get_main_queue()];
// And that's all that is needed.
// The module will receive any delegate methods it needs automatically
// from the xmpp stream, and will continue to do its thing unless you deactivate it.
當我們都加好要用的modules,就可以開始建立連線了!
NSError *error = nil;
if (![xmppStream connect:&error])
{
NSLog(@"Oops, I probably forgot something: %@", error);
}
若是我們在過程中忘記設定必須的屬性,例如JID,那連線就會回傳NO,並在error message中給予提示。
在連線過程中,client端和server端會建立xmpp handshake(交握),達成協定。如果你的伺服器需要建立安全連線,例如透過SSL/TLS方式,xmpp stream會自動建立安全連線。如果你的伺服器有不正確的X509 certificate,那就必須去實作xmppStream:willSecureWithSettings: 這個方法來改掉預設的安全設定。
5. 認證(Authenticating)
在所有連線handshaking都已經完成後,就會開始呼叫 xmppStreamDidConnect:方法,並開始進行認證程序。程式碼如下:
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
[xmppStream authenticateWithPassword:password error:NULL];
}
五個步驟進行完,在實際執行時就能與xmpp stream進行連線操作嘍!
參考連結:https://github.com/robbiehanson/XMPPFramework/wiki/IntroToFramework