common event parsing

This commit is contained in:
Maxim Devaev 2022-07-19 16:42:46 +03:00
parent b16359c53e
commit adf4be9bf7
3 changed files with 24 additions and 32 deletions

View File

@ -164,16 +164,16 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
async with self.__kvmd_session.ws() as self.__kvmd_ws: async with self.__kvmd_session.ws() as self.__kvmd_ws:
logger.info("[kvmd] %s: Connected to KVMD websocket", self._remote) logger.info("[kvmd] %s: Connected to KVMD websocket", self._remote)
self.__stage3_ws_connected.set_passed() self.__stage3_ws_connected.set_passed()
async for event in self.__kvmd_ws.communicate(): async for (event_type, event) in self.__kvmd_ws.communicate():
await self.__process_ws_event(event) await self.__process_ws_event(event_type, event)
raise RfbError("KVMD closed the websocket (the server may have been stopped)") raise RfbError("KVMD closed the websocket (the server may have been stopped)")
finally: finally:
self.__kvmd_ws = None self.__kvmd_ws = None
async def __process_ws_event(self, event: Dict) -> None: async def __process_ws_event(self, event_type: str, event: Dict) -> None:
if event["event_type"] == "info_meta_state": if event_type == "info_meta_state":
try: try:
host = event["event"]["server"]["host"] host = event["server"]["host"]
except Exception: except Exception:
host = None host = None
else: else:
@ -184,10 +184,10 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
await self._send_rename(name) await self._send_rename(name)
self.__shared_params.name = name self.__shared_params.name = name
elif event["event_type"] == "hid_state": elif event_type == "hid_state":
async with self.__lock: async with self.__lock:
if self._encodings.has_leds_state: if self._encodings.has_leds_state:
await self._send_leds_state(**event["event"]["keyboard"]["leds"]) await self._send_leds_state(**event["keyboard"]["leds"])
# ===== # =====

View File

@ -22,7 +22,6 @@
import asyncio import asyncio
import contextlib import contextlib
import json
import types import types
from typing import Tuple from typing import Tuple
@ -37,6 +36,7 @@ import aiohttp
from .. import aiotools from .. import aiotools
from .. import htclient from .. import htclient
from .. import htserver
# ===== # =====
@ -132,10 +132,10 @@ class KvmdClientWs:
def __init__(self, ws: aiohttp.ClientWebSocketResponse) -> None: def __init__(self, ws: aiohttp.ClientWebSocketResponse) -> None:
self.__ws = ws self.__ws = ws
self.__writer_queue: "asyncio.Queue[Dict]" = asyncio.Queue() self.__writer_queue: "asyncio.Queue[Tuple[str, Dict]]" = asyncio.Queue()
self.__communicated = False self.__communicated = False
async def communicate(self) -> AsyncGenerator[Dict, None]: async def communicate(self) -> AsyncGenerator[Tuple[str, Dict], None]:
assert not self.__communicated assert not self.__communicated
self.__communicated = True self.__communicated = True
receive_task: Optional[asyncio.Task] = None receive_task: Optional[asyncio.Task] = None
@ -152,7 +152,7 @@ class KvmdClientWs:
if receive_task in done: if receive_task in done:
msg = receive_task.result() msg = receive_task.result()
if msg.type == aiohttp.WSMsgType.TEXT: if msg.type == aiohttp.WSMsgType.TEXT:
yield json.loads(msg.data) yield htserver.parse_ws_event(msg.data)
elif msg.type == aiohttp.WSMsgType.CLOSE: elif msg.type == aiohttp.WSMsgType.CLOSE:
await self.__ws.close() await self.__ws.close()
elif msg.type == aiohttp.WSMsgType.CLOSED: elif msg.type == aiohttp.WSMsgType.CLOSED:
@ -162,7 +162,7 @@ class KvmdClientWs:
receive_task = None receive_task = None
if writer_task in done: if writer_task in done:
await self.__ws.send_str(json.dumps(writer_task.result())) await htserver.send_ws_event(self.__ws, *writer_task.result())
writer_task = None writer_task = None
finally: finally:
if receive_task: if receive_task:
@ -176,28 +176,16 @@ class KvmdClientWs:
self.__communicated = False self.__communicated = False
async def send_key_event(self, key: str, state: bool) -> None: async def send_key_event(self, key: str, state: bool) -> None:
await self.__writer_queue.put({ await self.__writer_queue.put(("key", {"key": key, "state": state}))
"event_type": "key",
"event": {"key": key, "state": state},
})
async def send_mouse_button_event(self, button: str, state: bool) -> None: async def send_mouse_button_event(self, button: str, state: bool) -> None:
await self.__writer_queue.put({ await self.__writer_queue.put(("mouse_button", {"button": button, "state": state}))
"event_type": "mouse_button",
"event": {"button": button, "state": state},
})
async def send_mouse_move_event(self, to_x: int, to_y: int) -> None: async def send_mouse_move_event(self, to_x: int, to_y: int) -> None:
await self.__writer_queue.put({ await self.__writer_queue.put(("mouse_move", {"to": {"x": to_x, "y": to_y}}))
"event_type": "mouse_move",
"event": {"to": {"x": to_x, "y": to_y}},
})
async def send_mouse_wheel_event(self, delta_x: int, delta_y: int) -> None: async def send_mouse_wheel_event(self, delta_x: int, delta_y: int) -> None:
await self.__writer_queue.put({ await self.__writer_queue.put(("mouse_wheel", {"delta": {"x": delta_x, "y": delta_y}}))
"event_type": "mouse_wheel",
"event": {"delta": {"x": delta_x, "y": delta_y}},
})
class KvmdClientSession: class KvmdClientSession:

View File

@ -208,6 +208,13 @@ async def stream_json_exception(response: StreamResponse, err: Exception) -> Non
}, False) }, False)
async def send_ws_event(wsr: WebSocketResponse, event_type: str, event: Optional[Dict]) -> None:
await wsr.send_str(json.dumps({
"event_type": event_type,
"event": event,
}))
def parse_ws_event(msg: str) -> Tuple[str, Dict]: def parse_ws_event(msg: str) -> Tuple[str, Dict]:
data = json.loads(msg) data = json.loads(msg)
if not isinstance(data, dict): if not isinstance(data, dict):
@ -246,10 +253,7 @@ class WsSession:
return f"WsSession(id={id(self)}, {self.kwargs})" return f"WsSession(id={id(self)}, {self.kwargs})"
async def send_event(self, event_type: str, event: Optional[Dict]) -> None: async def send_event(self, event_type: str, event: Optional[Dict]) -> None:
await self.wsr.send_str(json.dumps({ await send_ws_event(self.wsr, event_type, event)
"event_type": event_type,
"event": event,
}))
class HttpServer: class HttpServer: