sheave_server/net/
rtmp.rs

1use std::{
2    io::{
3        Error as IOError,
4        Result as IOResult
5    },
6    net::{
7        SocketAddr,
8        TcpListener as StdListener
9    },
10    task::{
11        Context,
12        Poll
13    }
14};
15use futures::ready;
16use tokio::net::{
17    TcpListener as TokioListener,
18    ToSocketAddrs
19};
20use sheave_core::net::rtmp::*;
21
22/// The default RTMP listener.
23#[derive(Debug)]
24pub struct RtmpListener {
25    tokio_listener: TokioListener
26}
27
28impl RtmpListener {
29    fn new(tokio_listener: TokioListener) -> Self {
30        Self { tokio_listener }
31    }
32
33    /// Opens a RTMP socket for remote host.
34    /// When binding succeeded, this wraps tokio's TcpListener into RtmpListener.
35    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.bind)
36    pub async fn bind<A: ToSocketAddrs>(addr: A) -> IOResult<Self> {
37        TokioListener::bind(addr).await.map(Self::new)
38    }
39
40    /// Accepts a new incoming connection from this listener.
41    /// When acceptance succeeded, this wraps tokio's TcpListener into RtmpListener.
42    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.accept)
43    pub async fn accept(&self) -> IOResult<(RtmpStream, SocketAddr)> {
44        let (tokio_stream, addr) = self.tokio_listener.accept().await?;
45        Ok((RtmpStream::from(tokio_stream), addr))
46    }
47
48    /// Polls to accept a new incoming connection to this listener.
49    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.poll_accept)
50    pub fn poll_accept(&self, cx: &mut Context<'_>) -> Poll<IOResult<(RtmpStream, SocketAddr)>> {
51        let (tokio_stream, addr) = ready!(self.tokio_listener.poll_accept(cx))?;
52        Poll::Ready(Ok((RtmpStream::from(tokio_stream), addr)))
53    }
54
55    /// Creates new RtmpListener from a `std::net::TcpListener`.
56    /// When binding succeeded, this wraps tokio's TcpListener into RtmpListener.
57    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.from_std)
58    pub fn from_std(std_listener: StdListener) -> IOResult<Self> {
59        TokioListener::from_std(std_listener).map(Self::new)
60    }
61
62    /// Turns a `sheave_core::net::rtmp::RtmpListener into `std::net::TcpListener`.
63    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.into_std)
64    pub fn into_std(self) -> IOResult<StdListener> {
65        self.tokio_listener.into_std()
66    }
67
68    /// Returns the local address that this listener is bound to.
69    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.local_addr)
70    pub fn local_addr(&self) -> IOResult<SocketAddr> {
71        self.tokio_listener.local_addr()
72    }
73
74    /// Gets the value of the IP_TTL option for this socket.
75    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.ttl)
76    pub fn ttl(&self) -> IOResult<u32> {
77        self.tokio_listener.ttl()
78    }
79
80    /// Sets the value for the IP_TTL option on this socket.
81    /// [Read more](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html#method.set_ttl)
82    pub fn set_ttl(&self, ttl: u32) -> IOResult<()> {
83        self.tokio_listener.set_ttl(ttl)
84    }
85}
86
87impl TryFrom<StdListener> for RtmpListener {
88    type Error = IOError;
89
90    fn try_from(std_listener: StdListener) -> IOResult<Self> {
91        Self::from_std(std_listener)
92    }
93}
94
95#[cfg(unix)]
96mod sys {
97    use std::os::unix::prelude::*;
98    use super::RtmpListener;
99
100    impl AsRawFd for RtmpListener {
101        fn as_raw_fd(&self) -> RawFd {
102            self.tokio_listener.as_raw_fd()
103        }
104    }
105
106    impl AsFd for RtmpListener {
107        fn as_fd(&self) -> BorrowedFd<'_> {
108            self.tokio_listener.as_fd()
109        }
110    }
111}
112
113#[cfg(any(all(doc, docsrs), windows))]
114#[cdg_attr(docsrs, doc(cfg(windows)))]
115mod sys {
116    use tokio::os::windows::io::{
117        AsRawSocket,
118        AsSocket,
119        BorrowedSocket,
120        Rawsocket
121    };
122    use super::RtmpListener;
123
124    impl AsRawSocket for RtmpListener {
125        fn as_raw_socket(&self) -> RawSocket {
126            self.tokio_listener.as_raw_socket()
127        }
128    }
129
130    impl AsSocket for RtmpListener {
131        fn as_socket(&self) -> BorrowedFd<'_> {
132            self.tokio_listener.as_socket()
133        }
134    }
135}
136
137#[cfg(all(tokio_unstable, target_os = "wasi"))]
138#[cfg_attr(docsrs, doc(cfg(tokio_unstable)))]
139mod sys {
140    use std::os::wasi::prelude::*;
141    use super::RtmpListener;
142
143    impl AsRawFd for RtmpListener {
144        fn as_raw_fd(&self) -> RawFd {
145            self.tokio_listener.as_raw_fd()
146        }
147    }
148
149    impl AsFd for RtmpListener {
150        fn as_fd(&self) -> BorrowedFd<'_> {
151            self.tokio_listener.as_fd()
152        }
153    }
154}