Skip to main content

CallbackServer

Struct CallbackServer 

Source
pub struct CallbackServer { /* private fields */ }
Expand description

HTTP callback server for receiving UPnP event notifications.

The CallbackServer binds to a local port and provides an HTTP endpoint for receiving UPnP NOTIFY requests. It validates UPnP headers and routes events through an EventRouter to a channel.

§Example

use tokio::sync::mpsc;
use callback_server::{CallbackServer, NotificationPayload};

#[tokio::main]
async fn main() {
    let (tx, mut rx) = mpsc::unbounded_channel::<NotificationPayload>();
     
    let server = CallbackServer::new((3400, 3500), tx)
        .await
        .expect("Failed to create callback server");
     
    println!("Server listening at: {}", server.base_url());
     
    // Process notifications
    while let Some(notification) = rx.recv().await {
        println!("Received event for subscription: {}", notification.subscription_id);
    }
}

Implementations§

Source§

impl CallbackServer

Source

pub async fn new( port_range: (u16, u16), event_sender: UnboundedSender<NotificationPayload>, ) -> Result<Self, String>

Create and start a new unified callback server.

This method creates a single HTTP server that efficiently handles all UPnP event notifications from multiple speakers and services. The server:

  • Finds an available port in the specified range
  • Detects the local IP address for callback URLs
  • Starts an HTTP server to receive all UPnP NOTIFY requests
  • Routes events through a unified event router to registered handlers
§Unified Event Stream Processing

The callback server is designed to support the unified event stream processor pattern where a single HTTP endpoint receives events from multiple UPnP services and speakers, then routes them to appropriate handlers based on subscription IDs.

§Arguments
  • port_range - Range of ports to try binding to (start, end)
  • event_sender - Channel for sending notification payloads to the unified processor
§Returns

Returns the callback server instance or an error if no port could be bound or the local IP address could not be detected.

§Example
let (tx, _rx) = mpsc::unbounded_channel::<NotificationPayload>();
let server = CallbackServer::new((3400, 3500), tx).await.unwrap();
println!("Unified callback server listening at: {}", server.base_url());
Source

pub fn base_url(&self) -> &str

Get the unified callback URL for subscription registration.

This URL should be used when subscribing to UPnP events from any speaker or service. The unified callback server will route all incoming events based on their subscription IDs to the appropriate handlers.

The format is http://<local_ip>:<port> and this same URL is used for all subscriptions, enabling the unified event stream processing pattern.

§Example
let callback_url = server.base_url();
println!("Use this URL for all subscriptions: {}", callback_url);
Source

pub fn port(&self) -> u16

Get the port the server is bound to.

Source

pub fn router(&self) -> &Arc<EventRouter>

Get a reference to the event router.

The router can be used to register and unregister subscription IDs for event routing.

§Example
server.router().register("uuid:subscription-123".to_string()).await;
Source

pub async fn shutdown(self) -> Result<(), String>

Shutdown the callback server gracefully.

Sends a shutdown signal to the HTTP server and waits for it to complete any in-flight requests.

§Example
server.shutdown().await.unwrap();

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more