Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 5, 2012 13:16:57

anemak
От:
Зарегистрирован: 2012-01-23
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Twisted и реконнект

Работаю с протоколом 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()
Тогда скрипт завершается. То есть все срабатывает корректно.

Как мне при разрыве соединения перезапустить реактор?



Офлайн

#2 Фев. 5, 2012 19:39:46

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Twisted и реконнект

Читай сорцы, там есть ответы на все твои вопросы, на вскидку, не проверял:

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

..bw



Отредактировано (Фев. 5, 2012 19:57:36)

Офлайн

#3 Фев. 6, 2012 12:06:22

anemak
От:
Зарегистрирован: 2012-01-23
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Twisted и реконнект

bw
p.s. И не надо говорить что НЕ РАБОТАЕТ, смотрим ошибку, traceback, сорцы и говорим ПОЧЕМУ не работает.
Это не будет работать хотя бы потому, ReconnectingClientFactory реализован для клиента, и вызывается совсем другими методами.



Офлайн

#4 Фев. 7, 2012 10:21:27

slav0nic
Команда
От: dp.ua
Зарегистрирован: 2006-05-07
Сообщения: 2260
Репутация: +  41  -
Профиль   Отправить e-mail  

Twisted и реконнект

эм, разве не

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

Офлайн

#5 Фев. 7, 2012 14:43:03

anemak
От:
Зарегистрирован: 2012-01-23
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Twisted и реконнект

slav0nic
эм, разве не
Код:

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

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


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

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

В общем беда.



Отредактировано (Фев. 7, 2012 14:46:20)

Офлайн

#6 Фев. 7, 2012 15:49:11

anemak
От:
Зарегистрирован: 2012-01-23
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Twisted и реконнект

Вот код бота:

#!/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



Отредактировано (Фев. 7, 2012 16:54:04)

Офлайн

#7 Фев. 9, 2012 17:09:12

anemak
От:
Зарегистрирован: 2012-01-23
Сообщения: 12
Репутация: +  0  -
Профиль   Отправить e-mail  

Twisted и реконнект

Проблему решил одной строчкой кода :) При срабатывании ConnectionLost создаю протокол заного через CallLater, если соединение не установлено, то вызывается ConnectionFailed который рекурсивно создаёт протокол с помощью CallLater до успешного подключения.



Отредактировано (Фев. 9, 2012 17:10:15)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version