App-level keepalive

This commit is contained in:
Dpeta 2022-08-14 20:44:28 +02:00
parent f78a9f97ac
commit 3d740658b0
4 changed files with 66 additions and 10 deletions

View file

@ -1,10 +1,17 @@
# Changelog
(This document uses YYYY-MM-DD)
## [v2.4.2] - 2022-07-08
## [v2.4.2] - 2022-08-14
### Added
- Application-level connection checks:
- Send ping if we haven't received any data from the server in 30 seconds.
- Show S3RV3R NOT R3SPOND1NG if the server hasn't responded in 45 seconds. (15 seconds after ping)
- Close connection and try to reconnect if the server hasn't responded in 90 seconds. (60 seconds after ping)
### Fixed
- Error when manually moving group.
- EOF on send not resulting in a disconnect.
## [v2.4.1] - 2022-07-05

14
irc.py
View file

@ -40,6 +40,7 @@ class PesterIRC(QtCore.QThread):
QtCore.QThread.__init__(self)
self.mainwindow = window
self.config = config
self.unresponsive = False
self.registeredIRC = False
self.metadata_supported = False
self.stopIRC = None
@ -68,6 +69,7 @@ class PesterIRC(QtCore.QThread):
res = True
try:
PchumLog.debug("updateIRC()")
self.mainwindow.sincerecv = 0
res = self.updateIRC()
except socket.timeout as se:
PchumLog.debug("timeout in thread %s" % (self))
@ -340,7 +342,8 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot()
def pingServer(self):
try:
self.cli.send("PING %s" % int(time.time()))
self.cli.send("PING :B33")
#self.cli.send("PING %s" % int(time.time()))
except OSError as e:
PchumLog.warning(e)
self.setConnectionBroken()
@ -537,6 +540,13 @@ class PesterHandler(DefaultCommandHandler):
self.parent.messageReceived.emit(handle, msg)
def pong(self, *args):
# source, server, token
#print("PONG", source, server, token)
#self.parent.mainwindow.lastrecv = time.time()
#print("PONG TIME: %s" % self.parent.mainwindow.lastpong)
pass
def welcome(self, server, nick, msg):
self.parent.setConnected()
#mychumhandle = self.mainwindow.profile().handle
@ -839,7 +849,7 @@ class PesterHandler(DefaultCommandHandler):
self.parent.userPresentUpdate.emit(handle, channel, "left")
def ping(self, prefix, server):
self.parent.mainwindow.lastping = int(time.time())
#self.parent.mainwindow.lastping = time.time()
self.client.send('PONG', server)
def getMood(self, *chums):

View file

@ -180,10 +180,10 @@ class IRCClient:
pass
else:
#raise se
_end = True # This ok?
self._end = True # This ok?
except AttributeError:
#raise se
_end = True # This ok?
self._end = True # This ok?
def connect(self):
""" initiates the connection to the server set in self.host:self.port
@ -222,6 +222,17 @@ class IRCClient:
self.socket.setblocking(False)
elif self.blocking:
self.socket.setblocking(True)
#try:
# self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
# if hasattr(socket, "TCP_KEEPIDLE"):
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 1)
# if hasattr(socket, "TCP_KEEPINTVL"):
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 1)
# if hasattr(socket, "TCP_KEEPCNT"):
# self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 1)
#except Exception as e:
# print(e)
helpers.nick(self, self.nick)
helpers.user(self, self.username, self.realname)

View file

@ -1500,8 +1500,8 @@ class PesterWindow(MovingWindow):
self.pingtimer = QtCore.QTimer()
self.pingtimer.timeout.connect(self.checkPing)
self.lastping = int(time.time())
self.pingtimer.start(1000*90)
self.sincerecv = 0 # Time since last recv
self.pingtimer.start(1000*15) # time in ms
self.mychumhandleLabel.adjustSize() # Required so "CHUMHANDLE:" regardless of style-sheet.
self.moodsLabel.adjustSize() # Required so "MOOD:" regardless of style-sheet.
@ -1545,10 +1545,36 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def checkPing(self):
curtime = int(time.time())
if curtime - self.lastping > 600:
'''Check if server is alive on app level,
this function is called every 15sec'''
# Return without irc
if hasattr(self.parent, 'irc') == False:
return
# Presume connection is dead after 90 seconds of silence.
if self.sincerecv >= 90:
self.disconnectIRC.emit()
# Show unresponsive if timing out
if self.sincerecv >= 45:
if self.parent.irc.unresponsive == False:
self.parent.irc.unresponsive = True
self.parent.showLoading(self.parent.widget,
"S3RV3R NOT R3SPOND1NG >:?")
self.show()
self.setFocus()
else:
self.parent.irc.unresponsive = False
if self.loadingscreen:
self.loadingscreen.done(QtWidgets.QDialog.DialogCode.Accepted)
# Send a ping if it's been 30 seconds since we've heard from the server.
if self.sincerecv >= 30:
self.pingServer.emit()
self.sincerecv += 15 # Only updating every 10s is better for performance.
def profile(self):
return self.userprofile.chat
def closeConversations(self, switch=False):
@ -3972,7 +3998,9 @@ class MainProgram(QtCore.QObject):
widget.loadingscreen.loadinglabel.setText(msg)
widget.loadingscreen.rejected.connect(widget.app.quit)
self.widget.loadingscreen.tryAgain.connect(self.tryAgain)
if hasattr(self, 'irc') and self.irc.registeredIRC:
if (hasattr(self, 'irc')
and self.irc.registeredIRC
and self.irc.unresponsive == False):
return
if self.reconnectok:
widget.loadingscreen.showReconnect()