Reimplement connection error handling

This commit is contained in:
Etoh 2019-01-26 15:37:50 +00:00 committed by Alberto Sottile
parent c7396d882d
commit 04ab645823
2 changed files with 34 additions and 36 deletions

View File

@ -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()

View File

@ -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__':