--- a/src/eric7/RemoteServer/EricServerDebuggerRequestHandler.py Sat Feb 10 11:28:58 2024 +0100 +++ b/src/eric7/RemoteServer/EricServerDebuggerRequestHandler.py Sun Feb 11 18:35:44 2024 +0100 @@ -17,6 +17,7 @@ from .EricRequestCategory import EricRequestCategory + class EricServerDebuggerRequestHandler: """ Class implementing the debugger request handler of the eric-ide server. @@ -132,6 +133,8 @@ self.__clientSocketDisconnected(sock) elif data: method = data["method"] + + # 1. process debug client messages before relaying if method == "DebuggerId" and sock in self.__pendingConnections: debuggerId = data['params']['debuggerId'] self.__connections[debuggerId] = sock @@ -143,7 +146,7 @@ # add an indicator for the eric-ide server data["params"]["platform"] += " (eric-ide Server)" - # pass on the data to the eric-ide + # 2. pass on the data to the eric-ide jsonStr = json.dumps(data) print("Client Response:", jsonStr) self.__server.sendJson( @@ -151,13 +154,19 @@ reply="DebugClientResponse", params={"response": jsonStr}, ) + + # 3. process debug client messages after relaying + if method == "ResponseExit": + for sock in list(self.__connections.values()): + if not self.__server.isSocketClosed(sock): + self.__clientSocketDisconnected(sock) def __clientSocketDisconnected(self, sock): """ - Private slot handling a socket disconnecting. + Private method handling a socket disconnecting. @param sock reference to the disconnected socket - @type QTcpSocket + @type socket.socket """ self.__server.getSelector().unregister(sock) @@ -178,7 +187,6 @@ if sock in self.__pendingConnections: self.__pendingConnections.remove(sock) - sock.shutdown(socket.SHUT_RDWR) sock.close() if not self.__connections: @@ -189,6 +197,16 @@ params={}, ) + def __mainClientExited(self): + """ + Private method to handle exiting of the main debug client. + """ + self.__server.sendJson( + category=EricRequestCategory.Debugger, + reply="MainClientExited", + params={"debugger_id": self.__mainClientId if self.__mainClientId else ""}, + ) + def __serviceDbgClientStdoutStderr(self, key): """ Private method to service the debug client stdout and stderr channels. @@ -238,7 +256,7 @@ def __shutdownSocket(self, debuggerId, sock): """ - Private slot to shut down a socket. + Private method to shut down a socket. @param debuggerId ID of the debugger the socket belongs to @type str @@ -309,7 +327,7 @@ ) # TODO: register stdin & stderr with selector - def __stopClient(self, params): + def __stopClient(self, params): # noqa: U100 """ Private method to stop the current debug client process. @@ -333,21 +351,17 @@ jsonStr = params["command"] print(debuggerId, "->", jsonStr) - if not debuggerId and self.__mainClientId: + if not debuggerId and self.__mainClientId and "RequestBanner" in jsonStr: + # modify the target for the 'RequestBanner' request debuggerId = self.__mainClientId - try: - sock = self.__connections[debuggerId] - except KeyError: - print(f"Command for unknown debugger ID '{debuggerId}' received.") - # tell the eric-ide again, that this debugger ID is gone - self.__server.sendJson( - category=EricRequestCategory.Debugger, - reply="DebugClientDisconnected", - params={"debugger_id": debuggerId}, - ) - sock = ( - self.__connections[self.__mainClientId] if self.__mainClientId else None - ) - if sock: - self.__server.sendJsonCommand(jsonStr, sock) + if debuggerId == "<<all>>": + # broadcast to all connected debug clients + for sock in self.__connections.values(): + self.__server.sendJsonCommand(jsonStr, sock) + else: + try: + sock = self.__connections[debuggerId] + self.__server.sendJsonCommand(jsonStr, sock) + except KeyError: + print(f"Command for unknown debugger ID '{debuggerId}' received.")