QWebSocket客户端无法连接到未创建时不监听的QWebSocketServer,也无法在服务器后续开始监听时连接
问题: 我想让客户端在服务器无法连接时,使用定时器发送ping或文本消息来重试连接。客户端希望从服务器收到pong或文本消息,以便开始处理一些数据。
服务器在前20秒内没有监听任何连接,这样做是为了模拟连接问题。20秒后,我让服务器开始监听,这样它就可以接受连接请求了。
如果客户端在第一次尝试连接时,或者在这20秒内没有监听的时间段内无法连接到服务器,即使服务器之后开始监听,客户端也不会再尝试连接。不过,如果我在服务器切换到监听状态后再运行客户端,一切就会正常工作。我该如何解决这个问题,让客户端能够发送ping或文本消息?现在看起来客户端进入了一个循环,这让它无法发送ping或文本消息。
客户端部分:
from time import sleep
import sys
from PySide6 import QtCore, QtWebSockets
from PySide6.QtCore import QUrl, QTimer
from PySide6.QtWidgets import QApplication
class Client(QtCore.QObject):
def __init__(self, parent):
super().__init__(parent)
self.client = QtWebSockets.QWebSocket("", QtWebSockets.QWebSocketProtocol.Version13, None)
self.client.open(QUrl("ws://127.0.0.1:6000"))
self.client.textMessageReceived.connect(self.process_message)
self.client.pong.connect(self.get_pong)
# self.client.error.connect(self.error)
self.date_list = ['2000-01-01']
self.check_status_timer = QTimer()
self.check_status_timer.timeout.connect(self.send_ping)
self.check_status_timer.start(2000)
# some data processing after connection established
def process(self, day):
print(f"Day {day}")
for i in range(10):
print(f"Sleeping {9 - i}")
sleep(.5)
print("emitted")
return True
def create_and_run(self):
current_date = self.date_list[0]
result = self.process(current_date)
if result:
self.send_message()
else:
print("PROCESS FAILED")
def process_message(self, message):
if message == "ping" or message == "True":
self.check_status_timer.stop()
self.create_and_run()
def get_pong(self):
print("PONG")
def send_ping(self):
print("SENDING PING")
self.client.ping()
self.client.sendTextMessage("ping")
def send_message(self):
self.client.sendTextMessage("Client0")
def error(self, error_code):
print("error code: {}".format(error_code))
if __name__ == "__main__":
app = QApplication(sys.argv)
client = Client(app)
app.exec()
服务器部分:
from PySide6 import QtCore, QtWebSockets, QtNetwork
from PySide6.QtWidgets import QApplication
class MyServer(QtCore.QObject):
def __init__(self, parent):
super().__init__(parent)
self.clients = []
self.server = QtWebSockets.QWebSocketServer(parent.serverName(), parent.secureMode(), parent)
self.server.acceptError.connect(self.on_accept_error)
self.server.newConnection.connect(self.on_new_connection)
# create timer so server will switch to listening state later
self.count = 0
self.timer_listen = QtCore.QTimer()
self.timer_listen.timeout.connect(self.make_listen)
self.timer_listen.start(2000)
def make_listen(self):
if self.count >= 10:
self.timer_listen.stop()
self.server.listen(QtNetwork.QHostAddress.LocalHost, 6000)
print(self.count, self.server.isListening())
else:
print(self.count, self.server.isListening())
self.count += 1
def on_accept_error(accept_error):
print("Accept Error: {}".format(accept_error))
def on_new_connection(self):
client_connection = self.server.nextPendingConnection()
client_connection.textMessageReceived.connect(self.process_message)
client_connection.disconnected.connect(self.disconnect)
self.clients.append(client_connection)
def process_message(self, message):
print(message)
if message == "ping":
self.sender().sendTextMessage("ping")
def disconnect(self):
if self.sender() in self.clients:
self.clients.remove(self.sender())
self.sender().deleteLater()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
serverObject = QtWebSockets.QWebSocketServer('My Socket', QtWebSockets.QWebSocketServer.NonSecureMode)
server = MyServer(serverObject)
serverObject.closed.connect(app.quit)
app.exec()
我尝试使用工作类来防止客户端的主循环冻结,也尝试了子类化QWebsocket,但都没有成功。
1 个回答
0
from time import sleep
import sys
from PySide6 import QtCore, QtWebSockets
from PySide6.QtCore import QUrl, QTimer
from PySide6.QtWidgets import QApplication
from PySide6.QtNetwork import QAbstractSocket
class Client(QtCore.QObject):
def __init__(self, parent):
super().__init__(parent)
self.client = QtWebSockets.QWebSocket("", QtWebSockets.QWebSocketProtocol.Version13, None)
self.client.textMessageReceived.connect(self.process_message)
self.client.pong.connect(self.get_pong)
# self.client.error.connect(self.error)
self.date_list = ['2000-01-01']
self.check_status_timer = QTimer()
self.check_status_timer.timeout.connect(self.send_ping)
self.check_status_timer.start(2000)
def process(self, day):
print(f"Day {day}")
for i in range(10):
print(f"Sleeping {9 - i}")
sleep(.5)
print("emitted")
return True
def create_and_run(self):
current_date = self.date_list[0]
result = self.process(current_date)
if result:
self.send_message()
else:
print("PROCESS FAILED")
def process_message(self, message):
if message == "ping" or message == "True":
self.check_status_timer.stop()
self.create_and_run()
def get_pong(self):
print("PONG")
def send_ping(self):
print("SENDING PING")
if self.client.state() == QAbstractSocket.SocketState.ConnectedState:
self.client.ping()
self.client.sendTextMessage("ping")
else:
self.client.open(QUrl("ws://127.0.0.1:6000"))
def send_message(self):
self.client.sendTextMessage("Client0")
def error(self, error_code):
print("error code: {}".format(error_code))
if __name__ == "__main__":
app = QApplication(sys.argv)
client = Client(app)
app.exec()