src/eric7/RemoteServerInterface/EricServerInterface.py

branch
server
changeset 10561
be23a662d709
parent 10555
08e853c0c77b
child 10565
3583a10ce4d4
diff -r 28b14d2df6a1 -r be23a662d709 src/eric7/RemoteServerInterface/EricServerInterface.py
--- a/src/eric7/RemoteServerInterface/EricServerInterface.py	Sat Feb 10 11:28:58 2024 +0100
+++ b/src/eric7/RemoteServerInterface/EricServerInterface.py	Sun Feb 11 18:35:44 2024 +0100
@@ -7,6 +7,7 @@
 Module implementing the interface to the eric remote server.
 """
 
+import collections
 import json
 import struct
 import uuid
@@ -85,6 +86,7 @@
 
         self.__connection = None
         self.__callbacks = {}  # callback references indexed by UUID
+        self.__messageQueue = collections.deque()
 
         self.connectionStateChanged.connect(self.__connectionStateChanged)
 
@@ -97,23 +99,31 @@
         @type str
         @return reference to the service interface
         @rtype QObject
+        @exception ValueError raised to indicate an unsupported server interface
+            was requested
         """
         lname = name.lower()
         try:
             return self.__serviceInterfaces[lname]
         except KeyError:
-            # instantiate the service interface
-            if lname == "filesystem":
-                from .EricServerFileSystemInterface import EricServerFileSystemInterface
-                self.__serviceInterfaces[lname] = EricServerFileSystemInterface(self)
-            elif lname == "debugger":
-                from .EricServerDebuggerInterface import EricServerDebuggerInterface
-                self.__serviceInterfaces[lname] = EricServerDebuggerInterface(self)
-            elif lname == "project":
-                # TODO: 'Project Interface' not implemented yet
-                pass
+            if lname not in ("debugger", "filesystem", "project"):
+                raise ValueError(f"no such service supported ({name})")
             else:
-                raise ValueError(f"no such service supported ({name})")
+                # instantiate the service interface
+                if lname == "filesystem":
+                    from .EricServerFileSystemInterface import (  # noqa: I101
+                        EricServerFileSystemInterface
+                    )
+                    self.__serviceInterfaces[lname] = (
+                        EricServerFileSystemInterface(self)
+                    )
+                elif lname == "debugger":
+                    from .EricServerDebuggerInterface import EricServerDebuggerInterface
+                    # noqa: I101
+                    self.__serviceInterfaces[lname] = EricServerDebuggerInterface(self)
+                elif lname == "project":
+                    # TODO: 'Project Interface' not implemented yet
+                    pass
 
             return self.__serviceInterfaces[lname]
 
@@ -123,7 +133,7 @@
 
     def connectToServer(self, host, port=None, timeout=None):
         """
-        Public method to connect to the given host and port
+        Public method to connect to the given host and port.
 
         @param host host name or IP address of the eric remote server
         @type str
@@ -132,6 +142,8 @@
         @param timeout timeout im seconds for the connection attempt
             (defaults to None)
         @type int (optional)
+        @return flag indicating success
+        @rtype bool
         """
         if not bool(port):  # None or 0
             # use default port
@@ -140,7 +152,7 @@
         if not bool(timeout):  # None or 0
             # use configured default timeout
             timeout = Preferences.getEricServer("ConnectionTimeout")
-        timeout = timeout * 1000  # convert to milliseconds
+        timeout *= 1000  # convert to milliseconds
 
         if self.__connection is not None:
             self.disconnectFromServer()
@@ -225,9 +237,6 @@
     def __receiveJson(self):
         """
         Private slot handling received data from the eric remote server.
-
-        @param idString id of the connection
-        @type str
         """
         while self.__connection and self.__connection.bytesAvailable():
             header = self.__connection.read(struct.calcsize(b"!II"))
@@ -238,7 +247,9 @@
                 maxSize = length - len(data)
                 if self.__connection.bytesAvailable() < maxSize:
                     self.__connection.waitForReadyRead(50)
-                data += self.__connection.read(maxSize)
+                newData = self.__connection.read(maxSize)
+                if newData:
+                    data += newData
 
             if zlib.adler32(data) & 0xFFFFFFFF != datahash:
                 # corrupted data -> discard and continue
@@ -246,7 +257,7 @@
 
             jsonString = data.decode("utf-8", "backslashreplace")
 
-            # - print("Remote Server Interface: {0}".format(jsonString))
+            # - print("Remote Server Interface Receive: {0}".format(jsonString))
             # - this is for debugging only
 
             try:
@@ -268,29 +279,34 @@
                 return
 
             reqUuid = serverDataDict["uuid"]
-            try:
+            if reqUuid:
+                # It is a response to a synchronous request -> handle the call back
+                # immediately.
                 self.__callbacks[reqUuid](
                     serverDataDict["reply"], serverDataDict["params"]
                 )
                 del self.__callbacks[reqUuid]
+            else:
+                self.__messageQueue.append(serverDataDict)
+
+        while self.__messageQueue:
+            serverDataDict = self.__messageQueue.popleft()  # get the first message
+            try:
+                self.__categorySignalMapping[serverDataDict["category"]].emit(
+                    serverDataDict["reply"], serverDataDict["params"]
+                )
             except KeyError:
-                # no callback for this UUID exists, send a signal
-                try:
-                    self.__categorySignalMapping[serverDataDict["category"]].emit(
+                if serverDataDict["category"] == EricRequestCategory.Error:
+                    # handle server errors in here
+                    self.__handleServerError(
                         serverDataDict["reply"], serverDataDict["params"]
                     )
-                except KeyError:
-                    if serverDataDict["category"] == EricRequestCategory.Error:
-                        # handle server errors in here
-                        self.__handleServerError(
-                            serverDataDict["reply"], serverDataDict["params"]
-                        )
-                    else:
-                        self.remoteReply.emit(
-                            serverDataDict["category"],
-                            serverDataDict["reply"],
-                            serverDataDict["params"],
-                        )
+                else:
+                    self.remoteReply.emit(
+                        serverDataDict["category"],
+                        serverDataDict["reply"],
+                        serverDataDict["params"],
+                    )
 
     def sendJson(self, category, request, params, callback=None, flush=False):
         """
@@ -309,9 +325,11 @@
             (defaults to False)
         @type bool (optional)
         """
-        reqUuid = str(uuid.uuid4())
         if callback:
+            reqUuid = str(uuid.uuid4())
             self.__callbacks[reqUuid] = callback
+        else:
+            reqUuid = ""
 
         serviceDict = {
             "jsonrpc": "2.0",
@@ -322,6 +340,9 @@
         }
         jsonString = json.dumps(serviceDict) + "\n"
 
+        # - print("Remote Server Interface Send: {0}".format(jsonString))
+        # - this is for debugging only
+
         if self.__connection is not None:
             data = jsonString.encode("utf8", "backslashreplace")
             header = struct.pack(b"!II", len(data), zlib.adler32(data) & 0xFFFFFFFF)
@@ -368,7 +389,10 @@
         @type dict
         @exception ValueError raised in case of an unsupported reply
         """
-        if reply == "Versions":
+        if reply != "Versions":
+            raise ValueError(f"unsupported reply received ({reply})")
+
+        else:
             versionText = self.tr("""<h2>Server Version Numbers</h2><table>""")
     
             # Python version
@@ -389,16 +413,13 @@
                 versionText,
             )
 
-        else:
-            raise ValueError(f"unsupported reply received ({reply})")
-
     #######################################################################
     ## Reply handler methods
     #######################################################################
 
     def __handleServerError(self, reply, params):
         """
-        Public method handling server error replies.
+        Private method handling server error replies.
 
         @param reply name of the error reply
         @type str
@@ -532,7 +553,7 @@
         @return the menu generated
         @rtype QMenu
         """
-        self.__serverProfilesMenu = QMenu(self.tr("Connect to"))##, self.__ui)
+        self.__serverProfilesMenu = QMenu(self.tr("Connect to"))
         self.__serverProfilesMenu.aboutToShow.connect(self.__showServerProfilesMenu)
         self.__serverProfilesMenu.triggered.connect(self.__serverProfileTriggered)
 
@@ -554,7 +575,6 @@
             ##"Recent": self.recentMenu,
         }
 
-
         return menu
 
     def initToolbar(self, toolbarManager):

eric ide

mercurial