Форум сайта python.su
Продолжаю изучать Twisted в свободное время и вот похоже упёрся в непонимание какой то базовой вещи. Тестовая задача простая написать сервер с клиентом, которые обмениваются данными раз в секунду при этом коннект авторизированный.
Код клиента конектится раз в секунду.
# -*- coding: utf-8 -*-
from twisted.spread import pb
from twisted.internet import reactor, task
from twisted.cred import credentials
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","bbb"))
def1.addCallbacks(self.good_connected, self.bad_connected)
def1.addCallback(self.send_data)
def1.addCallback(self.print_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 print_data(self, data):
print 'data ', data
def disconnect(self, perspective):
print 'disconnect'
reactor.stop()
if __name__ == "__main__":
st=login_send()
st.start()
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*arg
class MyRealm:
implements(portal.IRealm)
def requestAvatar(self, avatarId, mind, *interfaces):
if pb.IPerspective not in interfaces:
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()
Офлайн
Не рвите соединение, вот и всё. Или вы не понимаете, как на клиенте писать reactor.callLater(10, self.send_data) ?
Офлайн
Андрей СветловЧестно я довольного много всего пробовал, но всегда вылазят ошибки с которыми я не могу справится. Отсюда чувство что я не понимаю какой то базовой основы.
Не рвите соединение, вот и всё. Или вы не понимаете, как на клиенте писать reactor.callLater(10, self.send_data) ?
def1.addCallback(self.send_data)
def1.addCallback(self.print_data)
def1.addCallback(self.send_data)
def1.addCallback(self.print_data)
Офлайн
Забросил я Twisted, даже как-то стыдно…
def1.addCallback(self.send_all_data)
def send_all_data(self, p):
self.send_data(p).addCallback(self.print_data)
self.send_data(p).addCallback(self.print_data)
self.send_data(p).addCallback(self.print_data)
defers = [
self.send_data(p).addCallback(self.print_data),
self.send_data(p).addCallback(self.print_data),
self.send_data(p).addCallback(self.print_data)
]
group_defer = twisted.internet.defer.DeferredList(defers)
# или -- group_defer = twisted.internet.defer.gatherResults(defers)
# тут уж сам думай
self.data_stack = ['data1', 'data2']
def send_data(self, perspective, data):
return perspective.callRemote(data, self.count)
def some_behavior(self, remote):
data = self.data_stack.pop(0)
return\
.addCallback(lambda _: self.send_data(remote, data))\
.addCallback(self.print_data)\
.addCallback(lambda _: self.some_behavior(remote))
def1.addCallback(self.some_behavior)
Офлайн
Хм ваши коды работают. Предложение не дисконектится, и вынести в self мне понятны собственно в самом начале свои не рабочие попытки я начал с
def testTimeout(self):
# 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:
self.connection.addCallback(self.send_data).addCallback(self.print_data)
self.count+=1
def assign_connection(self):
# cache the connection.
self.connection = self.factory.login(credentials.UsernamePassword("test1","bbb"))
def send_data(self):
return self.connection.callRemote("foo", self.count)
def print_data(self, data):
print 'print_data', data
def send_data(self, p):
print 'p in send_data', p
if self.count==1:
self.remote_caller=p
else:
p=self.remote_caller
return p.callRemote("foo", self.count)
Офлайн
Не красиво, но сгодится для первого раза.
..bw
Офлайн