2011-07-27 23 views
1

學習扭曲。我決定寫一個服務器和客戶端,每秒一次共享數據。 寫了一個實現,但在我看來這是不正確的。Twisted task.loop and pb auth

# -*- coding: utf-8 -*- 

from twisted.spread import pb 
from twisted.internet import reactor, task 
from twisted.cred import credentials 
from win32com.server import factory 

class login_send: 

    def __init__(self): 
     self.count=0 
     self.timeout = 1.0 
     self.factory = pb.PBClientFactory() 
     reactor.connectTCP("localhost", 8800, self.factory) 

    def testTimeout(self): 
     self.count+=1 
     print self.count 

     def1 = self.factory.login(credentials.UsernamePassword("test1","bb1b")) 
     def1.addCallbacks(self.good_connected, self.bad_connected) 
     def1.addCallback(self.send_data) 
     def1.addErrback(self.disconnect) 
     if self.count>10:def1.addBoth(self.disconnect) 

    def start(self): 
     l = task.LoopingCall(self.testTimeout) 
     l.start(self.timeout) 
     reactor.run() 

    def good_connected(self, perspective): 
     print 'good login and password', perspective 
     return perspective 

    def bad_connected(self, perspective): 
     print 'bad login or password', perspective 
     return perspective 

    def send_data(self, perspective): 
     print 'send' 
     return perspective.callRemote("foo", self.count) 

    def disconnect(self, perspective): 
     print 'disconnect' 
     reactor.stop() 

if __name__ == "__main__": 
    st=login_send() 
    st.start() 

代碼:如果登錄名和密碼正確 - >發送self.count,如果登錄名或密碼錯誤 - >斷開,如果self.count> 10 - >斷開

第一個錯誤,在我看來,是我每次都必須登錄。

def1 = self.factory.login(credentials.UsernamePassword("test1", "bb1b")) 

如何使一個授權,並繼續發送每秒的數據?

簡單的測試服務器代碼:

from zope.interface import implements 

from twisted.spread import pb 
from twisted.cred import checkers, portal 
from twisted.internet import reactor 

class MyPerspective(pb.Avatar): 
    def __init__(self, name): 
     self.name = name 
    def perspective_foo(self, arg): 
     print "I am", self.name, "perspective_foo(",arg,") called on", self 
     return arg 

class MyRealm: 
    implements(portal.IRealm) 
    def requestAvatar(self, avatarId, mind, *interfaces): 
     if pb.IPerspective not in interfaces: 
      print 'qqqq' 
      raise NotImplementedError 
     return pb.IPerspective, MyPerspective(avatarId), lambda:None 

p = portal.Portal(MyRealm()) 
c = checkers.InMemoryUsernamePasswordDatabaseDontUse(test1="bbb", 
                user2="pass2") 
p.registerChecker(c) 
reactor.listenTCP(8800, pb.PBServerFactory(p)) 
reactor.run() 

回答

2

我相信這應該做的伎倆。

# Upper case first letter of class name is good policy. 
class Login_send: 

    def __init__(self): 
     # initialize the state variable to False. 
     self.connection = False 
     self.count=0 
     self.timeout = 1.0 
     self.factory = pb.PBClientFactory() 
     reactor.connectTCP("localhost", 8800, self.factory) 

    def testTimeout(self): 
     self.count+=1 
     print self.count 

     # no connection -- create one. 
     if not self.connection: 
      self.assign_connection() 

     # cached connection exists, call send_data manually. 
     elif self.count > 10: 
      self.disconnect(self.connection) 
     else: 
      #you probably want to send data only if it it should be valid. 
      self.send_data(self.connection)  

    def assign_connection(self): 
    ''' Creates and stores a Deffered which represents the connection to 
     the server. ''' 
     # cache the connection. 
     self.connection = self.factory.login(
           credentials.UsernamePassword("test1","bb1b")) 
     # add connection callbacks as normal. 
     self.connection.addCallbacks(
           self.good_connected, self.bad_connected) 
     self.connection.addCallback(self.send_data) 
     self.connection.addErrback(self.disconnect) 

    def disconnect(self, perspective): 
     # be sure to cleanup after yourself! 
     self.connection = False 
     print 'disconnect' 
     reactor.stop() 

    # the rest of your class goes here. 
+0

當使用您的代碼和密碼在這裏是正確的,我得到這個錯誤。文件「C:/Dropbox/my_py/test/client.py」,第72行,在send_data中 return perspective.callRemote(「foo」,self.count) exceptions.AttributeError:延遲實例沒有屬性'callRemote'。在開始時,我也嘗試編寫類似的代碼,但收到了無法修復的錯誤。我添加到發佈簡單的服務器。 – Echeg

+0

@Echeg如何在send_data中分配self.connection? – cwallenpoole

+0

可能有意義:self.send_data(self.connection) - > self.connection.addCallback(self.send_data) self.connection.addErrback(self.disconnect)並更改def send_data - > print'echo',perspective。 callRemote(「foo」,self.count) return perspective – Echeg