summaryrefslogtreecommitdiff
path: root/kvmd/apps/vnc/server.py
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2022-11-02 03:23:37 +0300
committerMaxim Devaev <[email protected]>2022-11-03 15:07:06 +0300
commit08241e92559cc037da4891e8c03b49b800fe43c1 (patch)
treed0221e1951a63d0ad761ea9abd172076ed6e8d93 /kvmd/apps/vnc/server.py
parentc57928a0f16ea4b5a1052ca00d616e56da82a274 (diff)
Implemented VNC ContinuousUpdates
Diffstat (limited to 'kvmd/apps/vnc/server.py')
-rw-r--r--kvmd/apps/vnc/server.py37
1 files changed, 28 insertions, 9 deletions
diff --git a/kvmd/apps/vnc/server.py b/kvmd/apps/vnc/server.py
index 25a6016f..0195cdd9 100644
--- a/kvmd/apps/vnc/server.py
+++ b/kvmd/apps/vnc/server.py
@@ -122,6 +122,8 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
self.__fb_notifier = aiotools.AioNotifier()
self.__fb_queue: "asyncio.Queue[dict]" = asyncio.Queue()
+ self.__fb_cont_updates = False
+ self.__fb_key_required = False
# Эти состояния шарить не обязательно - бекенд исключает дублирующиеся события.
# Все это нужно только чтобы не посылать лишние жсоны в сокет KVMD
@@ -198,14 +200,16 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
while True:
try:
streaming = False
- async for frame in streamer.read_stream():
- if not streaming:
- logger.info("%s [streamer]: Streaming ...", self._remote)
- streaming = True
- if frame["online"]:
- await self.__queue_frame(frame)
- else:
- await self.__queue_frame("No signal")
+ async with streamer.reading() as read_frame:
+ while True:
+ frame = await read_frame(self.__fb_key_required)
+ if not streaming:
+ logger.info("%s [streamer]: Streaming ...", self._remote)
+ streaming = True
+ if frame["online"]:
+ await self.__queue_frame(frame)
+ else:
+ await self.__queue_frame("No signal")
except StreamerError as err:
if isinstance(err, StreamerPermError):
streamer = self.__get_default_streamer()
@@ -284,6 +288,8 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
f" -> {last['width']}x{last['height']}\nPlease reconnect"
)
await self._send_fb_jpeg((await self.__make_text_frame(msg))["data"])
+ if self.__fb_cont_updates:
+ self.__fb_notifier.notify()
continue
await self._send_resize(last["width"], last["height"])
@@ -294,12 +300,18 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
if last["format"] == StreamFormats.JPEG:
await self._send_fb_jpeg(last["data"])
+ if self.__fb_cont_updates:
+ self.__fb_notifier.notify()
elif last["format"] == StreamFormats.H264:
if not self._encodings.has_h264:
raise RfbError("The client doesn't want to accept H264 anymore")
if has_h264_key:
+ self.__fb_key_required = False
await self._send_fb_h264(last["data"])
+ if self.__fb_cont_updates:
+ self.__fb_notifier.notify()
else:
+ self.__fb_key_required = True
self.__fb_notifier.notify()
else:
raise RuntimeError(f"Unknown format: {last['format']}")
@@ -413,7 +425,14 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
await self.__kvmd_session.streamer.set_params(quality, self.__desired_fps)
async def _on_fb_update_request(self) -> None:
- self.__fb_notifier.notify()
+ if not self.__fb_cont_updates:
+ self.__fb_notifier.notify()
+
+ async def _on_enable_cont_updates(self, enabled: bool) -> None:
+ get_logger(0).info("%s [main]: Applying ContUpdates=%s ...", self._remote, enabled)
+ self.__fb_cont_updates = enabled
+ if enabled:
+ self.__fb_notifier.notify()
# =====