Найти - Пользователи
Полная версия: Twisted и реконнект
Начало » Network » Twisted и реконнект
1
anemak
Работаю с протоколом ICQ в библиотеке Twisted.

class B(oscar.BOSConnection):
capabilities = [oscar.CAP_CHAT]
...
def connectionLost(self, reason):
print reason
...

class OA(oscar.OscarAuthenticator):
BOSClass = B

protocol.ClientCreator(reactor, OA, SN, PASS, icq=icqMode).connectTCP(*hostport)
reactor.run()
При разрыве соединения с интернетом, срабатывает connectionLost, получаю сообщение:
[Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion.]
Дальше скрипт просто висит, ничего не происходит. Что бы его остановить добавляю:

    def connectionLost(self, reason):
print reason
reactor.stop()
Тогда скрипт завершается. То есть все срабатывает корректно.

Как мне при разрыве соединения перезапустить реактор?
bw
Читай сорцы, там есть ответы на все твои вопросы, на вскидку, не проверял:
factory = protocol.ReconnectingClientFactory()
factory.protocol = lambda: oscar.OscarAuthenticator(SN, PASS, icq=icqMode)
reactor.connectTCP(host, port, factory)
p.s. И не надо говорить что НЕ РАБОТАЕТ, смотрим ошибку, traceback, сорцы и говорим ПОЧЕМУ не работает.

..bw
anemak
bw
p.s. И не надо говорить что НЕ РАБОТАЕТ, смотрим ошибку, traceback, сорцы и говорим ПОЧЕМУ не работает.
Это не будет работать хотя бы потому, ReconnectingClientFactory реализован для клиента, и вызывается совсем другими методами.
slav0nic
эм, разве не
def connectionLost(self, connector, reason):
connector.connect()
про “ … реализован для клиента”, что-то не совсем понял чем это плохо %)
anemak
slav0nic
эм, разве не
Код:

def connectionLost(self, connector, reason):
connector.connect()
про “ … реализован для клиента”, что-то не совсем понял чем это плохо %)
connectionLost не принимает аргумент connector )

Реализован для клиента - это значит, что когда соединение теряется клиентом (в данном случае я представляю из себя сервер), мы получаем событие clientConnectionLost и уже тогда вызываем connector.connect(). Ну а уже для этого имплементирован ReconnectingClientFactory, который позволяет делать реконнект пока не будет получено соединение.


Не знаю, два дня читал документацию, испробовал много вариантов, решения так и не нашёл.

Решил сделать велосипед: написал скрипт на баше, который проверяет каждые 5 минут скрипт, если он не запущен то запускает его … Но теперь столкнулся с тем, что при получении любой ошибки или исключения типа connectionLost или connectionFailed скрипт просто висит в консоли, и останавливается только Ctrl+C.

В общем беда.
anemak
Вот код бота:
#!/usr/bin/python
# -*- coding: windows-1251 -*-

from twisted.words.protocols import oscar
from twisted.internet import reactor, protocol

uin = "номер аськи"
passwort = "пароль"
hostport = ('login.icq.com', 5238)

class B(oscar.BOSConnection):
capabilities = [oscar.CAP_CHAT]
def initDone(self):
self.requestSelfInfo().addCallback(self.gotSelfInfo)
self.requestSSI().addCallback(self.gotBuddyList)
def gotSelfInfo(self, user):
print user.__dict__
self.name = user.name
def gotBuddyList(self, l):
print l
self.activateSSI()
self.setProfile("TEST!")
self.setIdleTime(0)
self.clientReady()
self.setAway()
def receiveMessage(self, user, multiparts, flags):
print "\n< From: ", user.name
print "< Message: ", unicode(multiparts[0][0], 'utf-16_be').encode('cp1251')
command = unicode(multiparts[0][0], 'utf-16_be').encode('cp1251').lower().split(' ')
PREF = "!"
if command[0] == (PREF+"comm"):
self.sendMessage(user.name, 'Ты заюзал комманду !comm')
else:
self.sendMessage(user.name, 'Низнаю такой комманды, юзай комманду !comm')
def connectionLost(self, reason):
print reason

class OA(oscar.OscarAuthenticator):
BOSClass = B

protocol.ClientCreator(reactor, OA, uin, passwort, icq=1).connectTCP(*hostport)
reactor.run()
Вот работа с ClientFactory:
from twisted.internet.protocol import Protocol, ReconnectingClientFactory
from sys import stdout

host = 'login.icq.com'
port = 5238

class Echo(Protocol):
def dataReceived(self, data):
stdout.write(data)

class EchoClientFactory(ReconnectingClientFactory):
def startedConnecting(self, connector):
print 'Started to connect.'

def buildProtocol(self, addr):
print 'Connected.'
print 'Resetting reconnection delay'
self.resetDelay()
return Echo()

def clientConnectionLost(self, connector, reason):
print 'Lost connection. Reason:', reason
ReconnectingClientFactory.clientConnectionLost(self, connector, reason) # Здесь мы будем коннектиться (при потере соединения) до тех пор, пока не подключимся.

def clientConnectionFailed(self, connector, reason):
print 'Connection failed. Reason:', reason
ReconnectingClientFactory.clientConnectionFailed(self, connector,
reason)

from twisted.internet import reactor
reactor.connectTCP(host, port, EchoClientFactory())
reactor.run()
Примеры: http://twistedmatrix.com/documents/current/core/howto/clients.html http://twistedmatrix.com/documents/current/core/howto/servers.html
anemak
Проблему решил одной строчкой кода :) При срабатывании ConnectionLost создаю протокол заного через CallLater, если соединение не установлено, то вызывается ConnectionFailed который рекурсивно создаёт протокол с помощью CallLater до успешного подключения.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB