callback-server
A generic UPnP callback server for receiving event notifications.
Overview
This is an internal implementation detail of sonos-sdk. It is published to crates.io as a transitive dependency but is not intended for direct use.
The callback-server crate provides a lightweight HTTP server for handling UPnP NOTIFY requests. It is completely generic and has no knowledge of device-specific protocols or implementations.
Purpose
This crate was extracted from device-specific implementations to:
- Separate HTTP server concerns from business logic
- Provide a reusable foundation for UPnP event handling
- Keep device-specific crates focused on their domain
- Enable easier testing and maintenance
Components
- CallbackServer: HTTP server that receives UPnP NOTIFY requests on a local port
- EventRouter: Routes incoming events based on subscription IDs
- NotificationPayload: Generic data structure containing subscription ID and event XML
Usage
This crate is used by adding it as a path dependency in other workspace crates:
[]
= { = "../callback-server" }
Device-specific crates should create adapter layers that wrap the generic types and add domain-specific context.
Adapter Pattern
The recommended pattern for using this crate is to create an adapter layer in the consuming crate:
- Create a channel for receiving generic
NotificationPayloadfrom callback-server - Spawn an adapter task that receives notifications and adds device-specific context
- Maintain a mapping from subscription IDs to device-specific information
- Convert generic notifications into domain-specific events
- Send enriched events to your application's event processor
Example adapter structure:
This pattern keeps the callback-server generic while allowing device-specific crates to add their own context and types.
Architecture
The callback-server is designed to be a thin layer that:
- Binds to an available port in a specified range
- Validates incoming UPnP NOTIFY requests
- Extracts subscription IDs and event XML
- Routes events to registered handlers via channels
All device-specific logic (speaker IDs, service types, event parsing) should be handled by the consuming crate.
Dependencies
tokio: Async runtimewarp: HTTP server frameworkbytes: Efficient byte buffer handling
Testing
Run tests from the crate directory:
Or from the workspace root: