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.protocol import ClientFactory
from twisted.internet import reactor, task, defer, threads
from twisted.application.internet import ClientService
from syncplay import utils, constants, version
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
@ -28,43 +29,11 @@ class SyncClientFactory(ClientFactory):
self._client = client
self.retry = retry
self._timesTried = 0
self.reconnecting = False
def buildProtocol(self, addr):
self._timesTried = 0
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):
def __init__(self, playerClass, ui, config):
constants.SHOW_OSD = config['showOSD']
@ -730,15 +699,41 @@ class SyncplayClient(object):
host = host.strip('[]')
port = int(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()
def stop(self, promptForAction=False):
if not self._running:
return
self._running = False
if self.protocolFactory:
self.protocolFactory.stopRetrying()
self.destroyProtocol()
if self._player:
self._player.drop()

View File

@ -24,7 +24,10 @@ class DualStackPort(tcp.Port):
def createInternetSocket(self):
s = tcp.Port.createInternetSocket(self)
try:
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
except:
pass
return s
if __name__ == '__main__':