mandrewcito / signalrcore

SignalR Core python client
https://mandrewcito.github.io/signalrcore/
MIT License
115 stars 53 forks source link

Application freezed after received message. #49

Open dawidwekwejt opened 3 years ago

dawidwekwejt commented 3 years ago

I'm working on desktop application based on PyQT and signalrcore library. My application freezed after recived a message from server.

Steps to reproduce the behavior:

  1. Create simple app with PyQT and signalrcore.
  2. Write code to handle messages from server
  3. In handler method call "showFullScreen()"

Expected behavior Application should open in full screen mode.

Desktop (please complete the following information):

Additional context This situation have place only when I execute showFullScreen() from inside of message handler method.

Building connection

self.connection = HubConnectionBuilder()\
    .with_url(self.hubUrl, options=
    {
        "skip_negotiation": False,
        "verify_ssl": True,
    })\
    .configure_logging(logging.ERROR)\
    .with_automatic_reconnect({
        "type": "interval",
        "keep_alive_interval": 10,
        "intervals": [1, 3, 5, 6, 7, 87, 3]
    }).build()

self.connection.on_open(lambda: self.onOpen())
self.connection.on_close(lambda: print("---- Disconnected ----"))
self.connection.on_error(lambda data: print("---- Error ----\n{data.error}\n---------------"))

self.connection.on("AwakeReceived", lambda data: self.onAwakeReceived(data))

self.connection.start()

Message handler method

def onAwakeReceived(self, data):
    print("---- Received data ----")

    # TODO

    self.showFullScreen()

I think the reason could be related with thread uesd to handle websocket. Is there posibility to inject QThread?

mandrewcito commented 3 years ago

When you call onAwakeReceived? You place showFullScreen just after 'self.connection.start()'. Connection is running on another thread it cant block your app.

I think that using the on_open method will solve your problem .Did you try this?

dawidwekwejt commented 3 years ago

I call onAwakeReceived() here: self.connection.on("AwakeReceived", lambda data: self.onAwakeReceived(data))

Without showFullScreen method onAwakeReceived working correctly and application never stoped.

I made yesterday at night a test where I run showFullScreen from QThread. In this test onAwakeReceived just set a flag which was checking by the QThread. If value of this flag was True I emited a signal. My signal handler was made for executing showFullScreen and the rest of UI logic. The result of this test was success. The window was opened in full screen and it wasn't freezed.

Yesterday night test

Worker definition

class WorkerThread(core.QThread):
    update = core.pyqtSignal()
    data = None

    def __init__(self, event):
        core.QThread.__init__(self)
        self.stopped = event
        self.flag = False

    def run(self):
        while True:
            if self.flag:
                print("TH FLAG: {}".format(self.flag))
                self.flag = not self.flag
                self.update.emit()

Start worker

worker_stop_flag = Event()
self.worker = WorkerThread(worker_stop_flag)
self.worker.update.connect(self.doWork)
self.worker.start()

UI signal handler

def doWork(self):
    print(self.worker.data)

    self.showFullScreen()

onAwakeReceived set flag for worker

def onAwakeReceived(self, data):
    print("UI FLAG: {}".format(self.worker.flag))
    self.worker.data = data
    self.worker.flag = True

Do You have any idea how do it without additional QThread?