Compare commits

..

2 commits

4 changed files with 10 additions and 41 deletions
schemata
src/mpd_now_playable
config
receivers/websockets

View file

@ -5,9 +5,6 @@
"kind": { "kind": {
"const": "cocoa", "const": "cocoa",
"default": "cocoa", "default": "cocoa",
"enum": [
"cocoa"
],
"title": "Kind", "title": "Kind",
"type": "string" "type": "string"
} }
@ -52,28 +49,14 @@
"WebsocketsReceiverConfig": { "WebsocketsReceiverConfig": {
"properties": { "properties": {
"host": { "host": {
"anyOf": [
{
"format": "hostname",
"type": "string"
},
{
"items": {
"format": "hostname",
"type": "string"
},
"type": "array"
}
],
"description": "The hostname you'd like your WebSockets server to listen on. In most cases the default behaviour, which binds to all network interfaces, will be fine.", "description": "The hostname you'd like your WebSockets server to listen on. In most cases the default behaviour, which binds to all network interfaces, will be fine.",
"title": "Host" "format": "hostname",
"title": "Host",
"type": "string"
}, },
"kind": { "kind": {
"const": "websockets", "const": "websockets",
"default": "websockets", "default": "websockets",
"enum": [
"websockets"
],
"title": "Kind", "title": "Kind",
"type": "string" "type": "string"
}, },

View file

@ -136,9 +136,6 @@
}, },
{ {
"const": "oneshot", "const": "oneshot",
"enum": [
"oneshot"
],
"type": "string" "type": "string"
} }
], ],
@ -172,9 +169,6 @@
}, },
{ {
"const": "oneshot", "const": "oneshot",
"enum": [
"oneshot"
],
"type": "string" "type": "string"
} }
], ],
@ -328,9 +322,6 @@
"state": { "state": {
"const": "stop", "const": "stop",
"default": "stop", "default": "stop",
"enum": [
"stop"
],
"title": "State", "title": "State",
"type": "string" "type": "string"
} }

View file

@ -35,7 +35,7 @@ class WebsocketsReceiverConfig(BaseReceiverConfig):
#: The hostname you'd like your WebSockets server to listen on. In most #: The hostname you'd like your WebSockets server to listen on. In most
#: cases the default behaviour, which binds to all network interfaces, will #: cases the default behaviour, which binds to all network interfaces, will
#: be fine. #: be fine.
host: Optional[Host | tuple[Host, ...]] = None host: Optional[Host] = None
ReceiverConfig = Annotated[ ReceiverConfig = Annotated[

View file

@ -2,7 +2,7 @@ from pathlib import Path
import ormsgpack import ormsgpack
from websockets import broadcast from websockets import broadcast
from websockets.server import WebSocketServerProtocol, serve from websockets.asyncio.server import Server, ServerConnection, serve
from yarl import URL from yarl import URL
from ...config.model import WebsocketsReceiverConfig from ...config.model import WebsocketsReceiverConfig
@ -24,12 +24,11 @@ def default(value: object) -> object:
class WebsocketsReceiver(Receiver): class WebsocketsReceiver(Receiver):
config: WebsocketsReceiverConfig config: WebsocketsReceiverConfig
player: Player player: Player
connections: set[WebSocketServerProtocol] server: Server
last_status: bytes = MSGPACK_NULL last_status: bytes = MSGPACK_NULL
def __init__(self, config: WebsocketsReceiverConfig): def __init__(self, config: WebsocketsReceiverConfig):
self.config = config self.config = config
self.connections = set()
@classmethod @classmethod
def loop_factory(cls) -> DefaultLoopFactory: def loop_factory(cls) -> DefaultLoopFactory:
@ -37,18 +36,14 @@ class WebsocketsReceiver(Receiver):
async def start(self, player: Player) -> None: async def start(self, player: Player) -> None:
self.player = player self.player = player
await serve( self.server = await serve(
self.handle, host=self.config.host, port=self.config.port, reuse_port=True self.handle, host=self.config.host, port=self.config.port, reuse_port=True
) )
async def handle(self, conn: WebSocketServerProtocol) -> None: async def handle(self, conn: ServerConnection) -> None:
self.connections.add(conn)
await conn.send(self.last_status) await conn.send(self.last_status)
try: await conn.wait_closed()
await conn.wait_closed()
finally:
self.connections.remove(conn)
async def update(self, playback: Playback) -> None: async def update(self, playback: Playback) -> None:
self.last_status = ormsgpack.packb(playback, default=default) self.last_status = ormsgpack.packb(playback, default=default)
broadcast(self.connections, self.last_status) broadcast(self.server.connections, self.last_status)