Reimplement connection error handling
This commit is contained in:
parent
c7396d882d
commit
04ab645823
@ -14,6 +14,7 @@ from functools import wraps
|
|||||||
from twisted.internet.endpoints import HostnameEndpoint
|
from twisted.internet.endpoints import HostnameEndpoint
|
||||||
from twisted.internet.protocol import ClientFactory
|
from twisted.internet.protocol import ClientFactory
|
||||||
from twisted.internet import reactor, task, defer, threads
|
from twisted.internet import reactor, task, defer, threads
|
||||||
|
from twisted.application.internet import ClientService
|
||||||
|
|
||||||
from syncplay import utils, constants, version
|
from syncplay import utils, constants, version
|
||||||
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
|
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
|
||||||
@ -28,43 +29,11 @@ class SyncClientFactory(ClientFactory):
|
|||||||
self._client = client
|
self._client = client
|
||||||
self.retry = retry
|
self.retry = retry
|
||||||
self._timesTried = 0
|
self._timesTried = 0
|
||||||
self.reconnecting = False
|
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
self._timesTried = 0
|
self._timesTried = 0
|
||||||
return SyncClientProtocol(self._client)
|
return SyncClientProtocol(self._client)
|
||||||
|
|
||||||
def startedConnecting(self, connector):
|
|
||||||
destination = connector.getDestination()
|
|
||||||
message = getMessage("connection-attempt-notification").format(destination.host, destination.port)
|
|
||||||
self._client.ui.showMessage(message)
|
|
||||||
|
|
||||||
def clientConnectionLost(self, connector, reason):
|
|
||||||
if self._timesTried == 0:
|
|
||||||
self._client.onDisconnect()
|
|
||||||
if self._timesTried < self.retry:
|
|
||||||
self._timesTried += 1
|
|
||||||
self._client.ui.showMessage(getMessage("reconnection-attempt-notification"))
|
|
||||||
self.reconnecting = True
|
|
||||||
reactor.callLater(0.1 * (2 ** min(self._timesTried, 5)), connector.connect)
|
|
||||||
else:
|
|
||||||
message = getMessage("disconnection-notification")
|
|
||||||
self._client.ui.showErrorMessage(message)
|
|
||||||
|
|
||||||
def clientConnectionFailed(self, connector, reason):
|
|
||||||
if not self.reconnecting:
|
|
||||||
reactor.callLater(0.1, self._client.ui.showErrorMessage, getMessage("connection-failed-notification"), True)
|
|
||||||
reactor.callLater(0.1, self._client.stop, True)
|
|
||||||
else:
|
|
||||||
self.clientConnectionLost(connector, reason)
|
|
||||||
|
|
||||||
def resetRetrying(self):
|
|
||||||
self._timesTried = 0
|
|
||||||
|
|
||||||
def stopRetrying(self):
|
|
||||||
self._timesTried = self.retry
|
|
||||||
|
|
||||||
|
|
||||||
class SyncplayClient(object):
|
class SyncplayClient(object):
|
||||||
def __init__(self, playerClass, ui, config):
|
def __init__(self, playerClass, ui, config):
|
||||||
constants.SHOW_OSD = config['showOSD']
|
constants.SHOW_OSD = config['showOSD']
|
||||||
@ -730,15 +699,41 @@ class SyncplayClient(object):
|
|||||||
host = host.strip('[]')
|
host = host.strip('[]')
|
||||||
port = int(port)
|
port = int(port)
|
||||||
self._endpoint = HostnameEndpoint(reactor, host, port)
|
self._endpoint = HostnameEndpoint(reactor, host, port)
|
||||||
self._endpoint.connect(self.protocolFactory)
|
|
||||||
|
def retry(retries):
|
||||||
|
self._lastGlobalUpdate = None
|
||||||
|
if retries == 0:
|
||||||
|
self.onDisconnect()
|
||||||
|
if retries > constants.RECONNECT_RETRIES:
|
||||||
|
reactor.callLater(0.1, self.ui.showErrorMessage, getMessage("connection-failed-notification"),
|
||||||
|
True)
|
||||||
|
reactor.callLater(0.1, self.stop, True)
|
||||||
|
return None
|
||||||
|
|
||||||
|
self.ui.showMessage(getMessage("reconnection-attempt-notification"))
|
||||||
|
self.reconnecting = True
|
||||||
|
return(0.1 * (2 ** min(retries, 5)))
|
||||||
|
|
||||||
|
self._reconnectingService = ClientService(self._endpoint, self.protocolFactory , retryPolicy=retry)
|
||||||
|
waitForConnection = self._reconnectingService.whenConnected(failAfterFailures=1)
|
||||||
|
self._reconnectingService.startService()
|
||||||
|
|
||||||
|
def connectedNow(f):
|
||||||
|
return
|
||||||
|
|
||||||
|
def failed(f):
|
||||||
|
reactor.callLater(0.1, self.ui.showErrorMessage, getMessage("connection-failed-notification"), True)
|
||||||
|
reactor.callLater(0.1, self.stop, True)
|
||||||
|
|
||||||
|
waitForConnection.addCallbacks(connectedNow, failed)
|
||||||
|
message = getMessage("connection-attempt-notification").format(host, port)
|
||||||
|
self.ui.showMessage(message)
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
||||||
def stop(self, promptForAction=False):
|
def stop(self, promptForAction=False):
|
||||||
if not self._running:
|
if not self._running:
|
||||||
return
|
return
|
||||||
self._running = False
|
self._running = False
|
||||||
if self.protocolFactory:
|
|
||||||
self.protocolFactory.stopRetrying()
|
|
||||||
self.destroyProtocol()
|
self.destroyProtocol()
|
||||||
if self._player:
|
if self._player:
|
||||||
self._player.drop()
|
self._player.drop()
|
||||||
|
|||||||
@ -24,7 +24,10 @@ class DualStackPort(tcp.Port):
|
|||||||
|
|
||||||
def createInternetSocket(self):
|
def createInternetSocket(self):
|
||||||
s = tcp.Port.createInternetSocket(self)
|
s = tcp.Port.createInternetSocket(self)
|
||||||
|
try:
|
||||||
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
return s
|
return s
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user