src/eric7/RemoteServer/EricServerDebuggerRequestHandler.py

branch
server
changeset 10767
b3672d3e7644
parent 10764
5915ca2466b2
child 10953
42166c630d9b
equal deleted inserted replaced
10766:d35d6f96c24b 10767:b3672d3e7644
14 import subprocess 14 import subprocess
15 import sys 15 import sys
16 import types 16 import types
17 17
18 from .EricRequestCategory import EricRequestCategory 18 from .EricRequestCategory import EricRequestCategory
19 19 from .EricServerBaseRequestHandler import EricServerBaseRequestHandler
20 20
21 class EricServerDebuggerRequestHandler: 21
22 class EricServerDebuggerRequestHandler(EricServerBaseRequestHandler):
22 """ 23 """
23 Class implementing the debugger request handler of the eric-ide server. 24 Class implementing the debugger request handler of the eric-ide server.
24 """ 25 """
25 26
26 def __init__(self, server): 27 def __init__(self, server):
28 Constructor 29 Constructor
29 30
30 @param server reference to the eric-ide server object 31 @param server reference to the eric-ide server object
31 @type EricServer 32 @type EricServer
32 """ 33 """
33 self.__server = server 34 super().__init__(server)
34 35
35 self.__requestMethodMapping = { 36 self._category = EricRequestCategory.Debugger
37
38 self._requestMethodMapping = {
36 "StartClient": self.__startClient, 39 "StartClient": self.__startClient,
37 "StopClient": self.__stopClient, 40 "StopClient": self.__stopClient,
38 "DebugClientCommand": self.__relayDebugClientCommand, 41 "DebugClientCommand": self.__relayDebugClientCommand,
39 } 42 }
40 43
63 f" {address[0]}, port {address[1]}" 66 f" {address[0]}, port {address[1]}"
64 ) 67 )
65 data = types.SimpleNamespace( 68 data = types.SimpleNamespace(
66 name="server", acceptHandler=self.__acceptDbgClientConnection 69 name="server", acceptHandler=self.__acceptDbgClientConnection
67 ) 70 )
68 self.__server.getSelector().register( 71 self._server.getSelector().register(
69 self.__socket, selectors.EVENT_READ, data=data 72 self.__socket, selectors.EVENT_READ, data=data
70 ) 73 )
71
72 def handleRequest(self, request, params, reqestUuid):
73 """
74 Public method handling the received debugger requests.
75
76 @param request request name
77 @type str
78 @param params dictionary containing the request parameters
79 @type dict
80 @param reqestUuid UUID of the associated request as sent by the eric IDE
81 @type str
82 """
83 try:
84 result = self.__requestMethodMapping[request](params)
85 if result:
86 self.__server.sendJson(
87 category=EricRequestCategory.Debugger,
88 reply=request,
89 params=result,
90 reqestUuid=reqestUuid,
91 )
92
93 except KeyError:
94 self.__server.sendJson(
95 category=EricRequestCategory.Debugger,
96 reply="DebuggerRequestError",
97 params={"Error": f"Request type '{request}' is not supported."},
98 )
99 74
100 ####################################################################### 75 #######################################################################
101 ## DebugServer like methods. 76 ## DebugServer like methods.
102 ####################################################################### 77 #######################################################################
103 78
117 data = types.SimpleNamespace( 92 data = types.SimpleNamespace(
118 name="debug_client", 93 name="debug_client",
119 address=address, 94 address=address,
120 handler=self.__serviceDbgClientConnection, 95 handler=self.__serviceDbgClientConnection,
121 ) 96 )
122 self.__server.getSelector().register( 97 self._server.getSelector().register(connection, selectors.EVENT_READ, data=data)
123 connection, selectors.EVENT_READ, data=data
124 )
125 98
126 def __serviceDbgClientConnection(self, key): 99 def __serviceDbgClientConnection(self, key):
127 """ 100 """
128 Private method to service the debug client connection. 101 Private method to service the debug client connection.
129 102
130 @param key reference to the SelectorKey object associated with the connection 103 @param key reference to the SelectorKey object associated with the connection
131 to be serviced 104 to be serviced
132 @type selectors.SelectorKey 105 @type selectors.SelectorKey
133 """ 106 """
134 sock = key.fileobj 107 sock = key.fileobj
135 data = self.__server.receiveJsonCommand(sock) 108 data = self._server.receiveJsonCommand(sock)
136 109
137 if data is None: 110 if data is None:
138 # socket was closed by debug client 111 # socket was closed by debug client
139 self.__clientSocketDisconnected(sock) 112 self.__clientSocketDisconnected(sock)
140 elif data: 113 elif data:
153 data["params"]["platform"] += " (eric-ide Server)" 126 data["params"]["platform"] += " (eric-ide Server)"
154 127
155 # 2. pass on the data to the eric-ide 128 # 2. pass on the data to the eric-ide
156 jsonStr = json.dumps(data) 129 jsonStr = json.dumps(data)
157 # - print("Client Response:", jsonStr) 130 # - print("Client Response:", jsonStr)
158 self.__server.sendJson( 131 self._server.sendJson(
159 category=EricRequestCategory.Debugger, 132 category=EricRequestCategory.Debugger,
160 reply="DebugClientResponse", 133 reply="DebugClientResponse",
161 params={"response": jsonStr}, 134 params={"response": jsonStr},
162 ) 135 )
163 136
164 # 3. process debug client messages after relaying 137 # 3. process debug client messages after relaying
165 if method == "ResponseExit": 138 if method == "ResponseExit":
166 for sock in list(self.__connections.values()): 139 for sock in list(self.__connections.values()):
167 if not self.__server.isSocketClosed(sock): 140 if not self._server.isSocketClosed(sock):
168 self.__clientSocketDisconnected(sock) 141 self.__clientSocketDisconnected(sock)
169 142
170 def __clientSocketDisconnected(self, sock): 143 def __clientSocketDisconnected(self, sock):
171 """ 144 """
172 Private method handling a socket disconnecting. 145 Private method handling a socket disconnecting.
173 146
174 @param sock reference to the disconnected socket 147 @param sock reference to the disconnected socket
175 @type socket.socket 148 @type socket.socket
176 """ 149 """
177 self.__server.getSelector().unregister(sock) 150 self._server.getSelector().unregister(sock)
178 151
179 address = sock.getpeername() 152 address = sock.getpeername()
180 print( # noqa: M801 153 print( # noqa: M801
181 f"'Debug Client' connection from {address[0]}, port {address[1]} closed." 154 f"'Debug Client' connection from {address[0]}, port {address[1]} closed."
182 ) 155 )
183 156
184 for debuggerId in list(self.__connections): 157 for debuggerId in list(self.__connections):
185 if self.__connections[debuggerId] is sock: 158 if self.__connections[debuggerId] is sock:
186 del self.__connections[debuggerId] 159 del self.__connections[debuggerId]
187 self.__server.sendJson( 160 self._server.sendJson(
188 category=EricRequestCategory.Debugger, 161 category=EricRequestCategory.Debugger,
189 reply="DebugClientDisconnected", 162 reply="DebugClientDisconnected",
190 params={"debugger_id": debuggerId}, 163 params={"debugger_id": debuggerId},
191 ) 164 )
192 165
202 175
203 def __mainClientExited(self): 176 def __mainClientExited(self):
204 """ 177 """
205 Private method to handle exiting of the main debug client. 178 Private method to handle exiting of the main debug client.
206 """ 179 """
207 self.__server.sendJson( 180 self._server.sendJson(
208 category=EricRequestCategory.Debugger, 181 category=EricRequestCategory.Debugger,
209 reply="MainClientExited", 182 reply="MainClientExited",
210 params={"debugger_id": self.__mainClientId if self.__mainClientId else ""}, 183 params={"debugger_id": self.__mainClientId if self.__mainClientId else ""},
211 ) 184 )
212 185
219 return 192 return
220 193
221 while self.__pendingConnections: 194 while self.__pendingConnections:
222 sock = self.__pendingConnections.pop() 195 sock = self.__pendingConnections.pop()
223 commandDict = self.__prepareClientCommand("RequestShutdown", {}) 196 commandDict = self.__prepareClientCommand("RequestShutdown", {})
224 self.__server.sendJsonCommand(commandDict, sock) 197 self._server.sendJsonCommand(commandDict, sock)
225 self.__shutdownSocket("", sock) 198 self.__shutdownSocket("", sock)
226 199
227 while self.__connections: 200 while self.__connections:
228 debuggerId, sock = self.__connections.popitem() 201 debuggerId, sock = self.__connections.popitem()
229 commandDict = self.__prepareClientCommand("RequestShutdown", {}) 202 commandDict = self.__prepareClientCommand("RequestShutdown", {})
230 self.__server.sendJsonCommand(commandDict, sock) 203 self._server.sendJsonCommand(commandDict, sock)
231 self.__shutdownSocket(debuggerId, sock) 204 self.__shutdownSocket(debuggerId, sock)
232 205
233 # reinitialize 206 # reinitialize
234 self.__mainClientId = None 207 self.__mainClientId = None
235 self.__client = None 208 self.__client = None
241 @param debuggerId ID of the debugger the socket belongs to 214 @param debuggerId ID of the debugger the socket belongs to
242 @type str 215 @type str
243 @param sock reference to the socket 216 @param sock reference to the socket
244 @type socket.socket 217 @type socket.socket
245 """ 218 """
246 self.__server.getSelector().unregister(sock) 219 self._server.getSelector().unregister(sock)
247 sock.shutdown(socket.SHUT_RDWR) 220 sock.shutdown(socket.SHUT_RDWR)
248 sock.close() 221 sock.close()
249 222
250 if debuggerId: 223 if debuggerId:
251 self.__server.sendJson( 224 self._server.sendJson(
252 category=EricRequestCategory.Debugger, 225 category=EricRequestCategory.Debugger,
253 reply="DebugClientDisconnected", 226 reply="DebugClientDisconnected",
254 params={"debugger_id": debuggerId}, 227 params={"debugger_id": debuggerId},
255 ) 228 )
256 229
295 ) 268 )
296 ) 269 )
297 ipaddr, port = self.__socket.getsockname() 270 ipaddr, port = self.__socket.getsockname()
298 args = [ 271 args = [
299 params["interpreter"] if params["interpreter"] else sys.executable, 272 params["interpreter"] if params["interpreter"] else sys.executable,
300 debugClient 273 debugClient,
301 ] 274 ]
302 args.extend(params["arguments"]) 275 args.extend(params["arguments"])
303 args.extend([str(port), "True", ipaddr]) 276 args.extend([str(port), "True", ipaddr])
304 277
305 workingDir = params["working_dir"] if params["working_dir"] else None 278 workingDir = params["working_dir"] if params["working_dir"] else None
344 debuggerId = self.__mainClientId 317 debuggerId = self.__mainClientId
345 318
346 if debuggerId == "<<all>>": 319 if debuggerId == "<<all>>":
347 # broadcast to all connected debug clients 320 # broadcast to all connected debug clients
348 for sock in self.__connections.values(): 321 for sock in self.__connections.values():
349 self.__server.sendJsonCommand(jsonStr, sock) 322 self._server.sendJsonCommand(jsonStr, sock)
350 else: 323 else:
351 try: # noqa: Y105 324 try: # noqa: Y105
352 sock = self.__connections[debuggerId] 325 sock = self.__connections[debuggerId]
353 self.__server.sendJsonCommand(jsonStr, sock) 326 self._server.sendJsonCommand(jsonStr, sock)
354 except KeyError: 327 except KeyError:
355 pass 328 pass
356 # - print(f"Command for unknown debugger ID '{debuggerId}' received.") 329 # - print(f"Command for unknown debugger ID '{debuggerId}' received.")

eric ide

mercurial