下面我們來看下驗證時客戶端要做了哪些事情,我還是以Demo當中的代碼來進行分析,這樣更容易接受,也更直觀,下面就是用戶登錄時驗證以及客戶端協議類的的主要代碼
# 該類的方法供服務端調用
class ClientRefrence(pb.Referenceable):
def remote_popupUserOnlineDlg(self):
PoupUiManager.PopupUserOnlineDlg()
class ClientHandler:
def __init__(self):
UiManager.Handler = self
def Connected(self,perspective):
self.perspective = perspective
# UiManager.MessageBox(u"登錄成功")
print "登錄成功"
# UiManager.LoginDlg().hide()
def Failed(self,reason):
# UiManager.MessageBox(reason.value)
self.connector.disconnect()
print reason.value
def Login(self,name,pwd):
factory = pb.PBClientFactory()
self.connector = reactor.connectTCP("192.168.1.109", 8206, factory)
d = factory.login(credentials.UsernamePassword(','.join((name,pwd)),''),client=ClientRefrence())
d.addCallback(self.Connected)
d.addCallback(self.NotifyOthserOnlineUsers)
d.addErrback(self.Failed)
return d
def callRemote(self,serverFunName,object=None):
self.perspective.callRemote(serverFunName)
def NotifyOthserOnlineUsers(self,object=None):
self.callRemote("NotifyOthserOnlineUsers")
其中,ClientHandler裏面的 Login 方法就是用戶登錄方法,裏面實現了twisted驗證時客戶端需要做的事情,那麼我們就來對代碼進行一行一行的分析:
----------------------------------------------------------------------
factory = pb.PBClientFactory()
self.connector = reactor.connectTCP("192.168.1.109", 8206, factory)
上面兩行主要是連接服務端,一旦與服務器連接上,會返回個可管理的連接對象,客戶端可以保存這個連接對象,在必要的時候可以關閉或者處理該連接,這裏保存在了
self.connector這個成員變量當中
----------------------------------------------------------------------
d = factory.login(credentials.UsernamePassword(','.join((name,pwd)),''),client=ClientRefrence())
上面一行主要是通過pb.PbClientFactory對象的Login方法向服務端發送驗證請求,該方法中包含了兩個參數,第一個參數指明瞭以何種凡是進行驗證,這裏通過實例化credentials.UsernamePassword對象指明瞭以用戶名/密碼對的驗證方式進行驗證,同事在實例化credentials.UsernamePassword的過程當中將用戶名和密碼以實參的形式
傳到服務端,這裏我進行了下小的調整,爲了滿足我個人Demo的需要,我將用戶名和密碼以逗號隔開憑藉成字符串的形式全部放到用戶名當中傳至服務端;第二個參數指明瞭
可以供服務端調用的客戶端協議,代碼中是ClientRefrence的實例化,該協議(ClientRefrence)必須繼承自pb.Refrenceable(遠程方法名以remote_開頭)或者是pb.Avator(遠程方法名以perspective_開頭)協議,繼承了該協議的類中的內部方法就可以供服務端調用(在服務端實現Portal.IRealm接口類重寫requestAvatorId方法中一形參的形式接受了該客戶端協議,可以將該客戶端協議保存至客戶端,以便於需要的時候直接通過調用其callRemote方法調用客戶端方法)。同時Login方法返回了一個defer異步對象,該一部對象提供了三個比較常用的方法addCallback()、addErrback()及addBoth(),addCallback()在調用成功的時候進行方法回調,addErrback()在調用失敗的時候進行方法回調,addBoth()不管是調用成功與否都進行方法回調
----------------------------------------------------------------------
d.addCallback(self.Connected)
d.addCallback(self.NotifyOthserOnlineUsers)
d.addErrback(self.Failed)
上面三行利用Login()方法返回的異步對象設置了不同情況的回調方法。當調用成功時回調Connected方法,Connected方法接受了一個perspective參數,該參數就是由服務端返回的一個協議,該協議在服務端繼承了pb.Refrenceable或pb.Avator協議,客戶端可以通過該協議調用服務端方法,當調用失敗時,回調Failed方法,記錄錯誤信息