Skip to content

Commit 1ad100c

Browse files
authored
A few small follow-up fixes (#303)
1 parent f5f9126 commit 1ad100c

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

aioslimproto/client.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ def __init__(
104104

105105
def disconnect(self) -> None:
106106
"""Disconnect and/or cleanup socket client."""
107+
self._connected = False
107108
if self._reader_task and not self._reader_task.done():
108109
self._reader_task.cancel()
109110
if self._heartbeat_task and not self._heartbeat_task.done():
110111
self._heartbeat_task.cancel()
111112

112-
if self._connected:
113-
self._connected = False
114-
if self._writer.can_write_eof():
115-
self._writer.write_eof()
113+
if self._writer.can_write_eof():
114+
self._writer.write_eof()
115+
if not self._writer.is_closing():
116116
self._writer.close()
117117

118118
async def configure_display(
@@ -388,7 +388,7 @@ async def play_url(
388388
but wait for the buffer to be full.
389389
- send_flush: advanced option to flush the buffer before playback.
390390
"""
391-
self.logger.debug("play url: %s", url)
391+
self.logger.debug("play url (enqueue: %s): %s", enqueue, url)
392392
if not url.startswith("http"):
393393
raise UnsupportedContentType(f"Invalid URL: {url}") # noqa: TRY003
394394

@@ -559,7 +559,7 @@ async def _send_heartbeat(self) -> None:
559559
replay_gain=heartbeat_id,
560560
)
561561
await self._render_display()
562-
await asyncio.sleep(5)
562+
await asyncio.sleep(HEARTBEAT_INTERVAL)
563563

564564
async def _socket_reader(self) -> None:
565565
"""Handle incoming data from socket."""
@@ -569,7 +569,7 @@ async def _socket_reader(self) -> None:
569569
try:
570570
async with timeout(HEARTBEAT_INTERVAL * 2):
571571
data = await self._reader.read(64)
572-
except TimeoutError:
572+
except (TimeoutError, ConnectionResetError):
573573
break
574574
# handle incoming data from socket
575575
buffer = buffer + data
@@ -581,6 +581,8 @@ async def _socket_reader(self) -> None:
581581
if len(buffer) >= plen:
582582
packet, buffer = buffer[8:plen], buffer[plen:]
583583
operation = operation.strip(b"!").strip().decode().lower()
584+
if operation == "bye!":
585+
break
584586
handler = getattr(self, f"_process_{operation}", None)
585587
if handler is None:
586588
self.logger.debug("No handler for %s", operation)
@@ -589,6 +591,7 @@ async def _socket_reader(self) -> None:
589591
else:
590592
asyncio.get_running_loop().call_soon(handler, packet)
591593
# EOF reached: socket is disconnected
594+
self._connected = False
592595
self.logger.debug(
593596
"Socket disconnected: %s",
594597
self._writer.get_extra_info("peername"),
@@ -775,6 +778,10 @@ def _process_stat_stmc(self, data: bytes) -> None:
775778
self.logger.debug("STMc received - connected.")
776779
# srtm-s command received. Guaranteed to be the first response to an strm-s.
777780
self._state = PlayerState.BUFFERING
781+
self._current_media = self._next_media
782+
self._next_media = None
783+
self.extra_data["playlist_timestamp"] = int(time.time())
784+
self.signal_update()
778785

779786
def _process_stat_stmd(self, data: bytes) -> None:
780787
"""Process incoming stat STMd message (decoder ready)."""
@@ -833,9 +840,6 @@ async def _process_stat_stms(self, data: bytes) -> None:
833840
"""Process incoming stat STMs message: Playback of new track has started."""
834841
self.logger.debug("STMs received - playback of new track has started")
835842
self._state = PlayerState.PLAYING
836-
self._current_media = self._next_media
837-
self._next_media = None
838-
self.extra_data["playlist_timestamp"] = int(time.time())
839843
self.signal_update()
840844
await self._render_display("playback_start")
841845

@@ -925,7 +929,11 @@ async def _process_resp(self, data: bytes) -> None:
925929
await self.send_frame(b"codc", codc_msg)
926930

927931
# parse ICY metadata
928-
if "icy-name" in headers and not self.next_media.metadata.get("title"):
932+
if (
933+
"icy-name" in headers
934+
and self._next_media
935+
and not self._next_media.metadata.get("title")
936+
):
929937
self._next_media.metadata["title"] = headers["icy-name"]
930938

931939
# send continue (used when autoplay 1 or 3)

aioslimproto/server.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,17 @@ def client_callback(
168168
return
169169

170170
if event_type == EventType.PLAYER_CONNECTED:
171-
prev = self._players.pop(player_id, None)
172-
if prev is not None:
171+
if (existing := self._players.get(player_id)) and existing.connected:
172+
# duplicate connection! we should ignore this
173+
self.logger.warning(
174+
"Duplicate connection detected for player %s",
175+
player_id,
176+
)
177+
client.disconnect()
178+
return
179+
if existing:
173180
# player reconnected while we did not yet cleanup the old socket
174-
prev.disconnect()
181+
existing.disconnect()
175182

176183
self._players[player_id] = client
177184

0 commit comments

Comments
 (0)