mirror of https://github.com/stjepang/smol
Remove uses of async-net
This commit is contained in:
parent
2d673d7f5e
commit
9c28a276fa
|
@ -42,7 +42,6 @@ async-channel = "1.1.1"
|
|||
async-dup = "1.1.0"
|
||||
async-h1 = "1.1.2"
|
||||
async-native-tls = "0.3.3"
|
||||
async-net = "0.1.0"
|
||||
async-std = "1.5.0"
|
||||
async-tungstenite = { version = "0.4.2", features = ["async-native-tls"] }
|
||||
base64 = "0.12.0"
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
//! cargo run --example async-h1-client
|
||||
//! ```
|
||||
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
|
||||
use anyhow::{bail, Context as _, Error, Result};
|
||||
use async_net::TcpStream;
|
||||
use blocking::block_on;
|
||||
use async_io::Async;
|
||||
use blocking::{block_on, unblock};
|
||||
use futures::prelude::*;
|
||||
use http_types::{Method, Request, Response};
|
||||
use url::Url;
|
||||
|
@ -23,8 +25,13 @@ async fn fetch(req: Request) -> Result<Response> {
|
|||
.context("cannot guess port")?;
|
||||
|
||||
// Connect to the host.
|
||||
let addr = format!("{}:{}", host, port);
|
||||
let stream = TcpStream::connect(addr).await?;
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
let stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
|
||||
// Send the request and wait for the response.
|
||||
let resp = match req.url().scheme() {
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
//!
|
||||
//! Refer to `README.md` to see how to the TLS certificate was generated.
|
||||
|
||||
use std::net::TcpListener;
|
||||
|
||||
use anyhow::Result;
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Identity, TlsAcceptor};
|
||||
use async_net::TcpListener;
|
||||
use blocking::block_on;
|
||||
use futures::prelude::*;
|
||||
use http_types::{Request, Response, StatusCode};
|
||||
|
@ -32,11 +34,11 @@ async fn serve(req: Request) -> http_types::Result<Response> {
|
|||
}
|
||||
|
||||
/// Listens for incoming connections and serves them.
|
||||
async fn listen(listener: TcpListener, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
// Format the full host address.
|
||||
let host = match &tls {
|
||||
None => format!("http://{}", listener.local_addr()?),
|
||||
Some(_) => format!("https://{}", listener.local_addr()?),
|
||||
None => format!("http://{}", listener.get_ref().local_addr()?),
|
||||
Some(_) => format!("https://{}", listener.get_ref().local_addr()?),
|
||||
};
|
||||
println!("Listening on {}", host);
|
||||
|
||||
|
@ -86,8 +88,11 @@ fn main() -> Result<()> {
|
|||
|
||||
// Start HTTP and HTTPS servers.
|
||||
block_on(async {
|
||||
let http = listen(TcpListener::bind("127.0.0.1:8000").await?, None);
|
||||
let https = listen(TcpListener::bind("127.0.0.1:8001").await?, Some(tls));
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
//! cargo run --example chat-client
|
||||
//! ```
|
||||
|
||||
use async_net::TcpStream;
|
||||
use std::net::TcpStream;
|
||||
|
||||
use async_io::Async;
|
||||
use blocking::{block_on, Unblock};
|
||||
use futures::io;
|
||||
use futures::prelude::*;
|
||||
|
@ -20,17 +22,17 @@ use futures::prelude::*;
|
|||
fn main() -> io::Result<()> {
|
||||
block_on(async {
|
||||
// Connect to the server and create async stdin and stdout.
|
||||
let stream = TcpStream::connect("127.0.0.1:6000").await?;
|
||||
let stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 6000)).await?;
|
||||
let stdin = Unblock::new(std::io::stdin());
|
||||
let mut stdout = Unblock::new(std::io::stdout());
|
||||
|
||||
// Intro messages.
|
||||
println!("Connected to {}", stream.peer_addr()?);
|
||||
println!("My nickname: {}", stream.local_addr()?);
|
||||
println!("Connected to {}", stream.get_ref().peer_addr()?);
|
||||
println!("My nickname: {}", stream.get_ref().local_addr()?);
|
||||
println!("Type a message and hit enter!\n");
|
||||
|
||||
let reader = &stream;
|
||||
let mut writer = stream.clone();
|
||||
let mut writer = &stream;
|
||||
|
||||
// Wait until the standard input is closed or the connection is closed.
|
||||
futures::select! {
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
//! ```
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream};
|
||||
|
||||
use async_channel::{bounded, Receiver, Sender};
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use async_dup::Arc;
|
||||
use async_io::Async;
|
||||
use blocking::block_on;
|
||||
use futures::io::{self, BufReader};
|
||||
use futures::prelude::*;
|
||||
|
@ -25,7 +26,7 @@ use smol::Task;
|
|||
/// An event on the chat server.
|
||||
enum Event {
|
||||
/// A client has joined.
|
||||
Join(SocketAddr, TcpStream),
|
||||
Join(SocketAddr, Arc<Async<TcpStream>>),
|
||||
|
||||
/// A client has left.
|
||||
Leave(SocketAddr),
|
||||
|
@ -37,7 +38,7 @@ enum Event {
|
|||
/// Dispatches events to clients.
|
||||
async fn dispatch(receiver: Receiver<Event>) -> io::Result<()> {
|
||||
// Currently active clients.
|
||||
let mut map = HashMap::<SocketAddr, TcpStream>::new();
|
||||
let mut map = HashMap::<SocketAddr, Arc<Async<TcpStream>>>::new();
|
||||
|
||||
// Receive incoming events.
|
||||
while let Ok(event) = receiver.recv().await {
|
||||
|
@ -67,8 +68,8 @@ async fn dispatch(receiver: Receiver<Event>) -> io::Result<()> {
|
|||
}
|
||||
|
||||
/// Reads messages from the client and forwards them to the dispatcher task.
|
||||
async fn read_messages(sender: Sender<Event>, client: TcpStream) -> io::Result<()> {
|
||||
let addr = client.peer_addr()?;
|
||||
async fn read_messages(sender: Sender<Event>, client: Arc<Async<TcpStream>>) -> io::Result<()> {
|
||||
let addr = client.get_ref().peer_addr()?;
|
||||
let mut lines = BufReader::new(client).lines();
|
||||
|
||||
while let Some(line) = lines.next().await {
|
||||
|
@ -81,10 +82,10 @@ async fn read_messages(sender: Sender<Event>, client: TcpStream) -> io::Result<(
|
|||
fn main() -> io::Result<()> {
|
||||
block_on(async {
|
||||
// Create a listener for incoming client connections.
|
||||
let listener = TcpListener::bind("127.0.0.1:6000").await?;
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 6000))?;
|
||||
|
||||
// Intro messages.
|
||||
println!("Listening on {}", listener.local_addr()?);
|
||||
println!("Listening on {}", listener.get_ref().local_addr()?);
|
||||
println!("Start a chat client now!\n");
|
||||
|
||||
// Spawn a background task that dispatches events to clients.
|
||||
|
@ -94,7 +95,7 @@ fn main() -> io::Result<()> {
|
|||
loop {
|
||||
// Accept the next connection.
|
||||
let (stream, addr) = listener.accept().await?;
|
||||
let client = stream;
|
||||
let client = Arc::new(stream);
|
||||
let sender = sender.clone();
|
||||
|
||||
// Spawn a background task reading messages from the client.
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
|
||||
use std::io;
|
||||
use std::net::Shutdown;
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::{bail, Context as _, Error, Result};
|
||||
use async_io::Async;
|
||||
use async_native_tls::TlsStream;
|
||||
use async_net::TcpStream;
|
||||
use blocking::block_on;
|
||||
use blocking::{block_on, unblock};
|
||||
use futures::prelude::*;
|
||||
use http::Uri;
|
||||
use hyper::{Body, Client, Request, Response};
|
||||
|
@ -81,14 +82,26 @@ impl hyper::service::Service<Uri> for SmolConnector {
|
|||
|
||||
match uri.scheme_str() {
|
||||
Some("http") => {
|
||||
let addr = format!("{}:{}", uri.host().unwrap(), uri.port_u16().unwrap_or(80));
|
||||
let stream = TcpStream::connect(addr).await?;
|
||||
let socket_addr = {
|
||||
let host = host.to_string();
|
||||
let port = uri.port_u16().unwrap_or(80);
|
||||
unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
let stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
Ok(SmolStream::Plain(stream))
|
||||
}
|
||||
Some("https") => {
|
||||
// In case of HTTPS, establish a secure TLS connection first.
|
||||
let addr = format!("{}:{}", uri.host().unwrap(), uri.port_u16().unwrap_or(443));
|
||||
let stream = TcpStream::connect(addr).await?;
|
||||
let socket_addr = {
|
||||
let host = host.to_string();
|
||||
let port = uri.port_u16().unwrap_or(443);
|
||||
unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
let stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
let stream = async_native_tls::connect(host, stream).await?;
|
||||
Ok(SmolStream::Tls(stream))
|
||||
}
|
||||
|
@ -101,10 +114,10 @@ impl hyper::service::Service<Uri> for SmolConnector {
|
|||
/// A TCP or TCP+TLS connection.
|
||||
enum SmolStream {
|
||||
/// A plain TCP connection.
|
||||
Plain(TcpStream),
|
||||
Plain(Async<TcpStream>),
|
||||
|
||||
/// A TCP connection secured by TLS.
|
||||
Tls(TlsStream<TcpStream>),
|
||||
Tls(TlsStream<Async<TcpStream>>),
|
||||
}
|
||||
|
||||
impl hyper::client::connect::Connection for SmolStream {
|
||||
|
@ -148,7 +161,7 @@ impl tokio::io::AsyncWrite for SmolStream {
|
|||
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
match &mut *self {
|
||||
SmolStream::Plain(s) => {
|
||||
s.shutdown(Shutdown::Write)?;
|
||||
s.get_ref().shutdown(Shutdown::Write)?;
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
SmolStream::Tls(s) => Pin::new(s).poll_close(cx),
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
|
||||
use std::io;
|
||||
use std::net::Shutdown;
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use blocking::block_on;
|
||||
use futures::prelude::*;
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
|
@ -34,11 +35,11 @@ async fn serve(req: Request<Body>, host: String) -> Result<Response<Body>> {
|
|||
}
|
||||
|
||||
/// Listens for incoming connections and serves them.
|
||||
async fn listen(listener: TcpListener, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
// Format the full host address.
|
||||
let host = &match tls {
|
||||
None => format!("http://{}", listener.local_addr()?),
|
||||
Some(_) => format!("https://{}", listener.local_addr()?),
|
||||
None => format!("http://{}", listener.get_ref().local_addr()?),
|
||||
Some(_) => format!("https://{}", listener.get_ref().local_addr()?),
|
||||
};
|
||||
println!("Listening on {}", host);
|
||||
|
||||
|
@ -61,8 +62,11 @@ fn main() -> Result<()> {
|
|||
|
||||
// Start HTTP and HTTPS servers.
|
||||
block_on(async {
|
||||
let http = listen(TcpListener::bind("127.0.0.1:8000").await?, None);
|
||||
let https = listen(TcpListener::bind("127.0.0.1:8001").await?, Some(tls));
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
|
@ -80,12 +84,12 @@ impl<F: Future + Send + 'static> hyper::rt::Executor<F> for SmolExecutor {
|
|||
|
||||
/// Listens for incoming connections.
|
||||
struct SmolListener {
|
||||
listener: TcpListener,
|
||||
listener: Async<TcpListener>,
|
||||
tls: Option<TlsAcceptor>,
|
||||
}
|
||||
|
||||
impl SmolListener {
|
||||
fn new(listener: TcpListener, tls: Option<TlsAcceptor>) -> Self {
|
||||
fn new(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Self {
|
||||
Self { listener, tls }
|
||||
}
|
||||
}
|
||||
|
@ -122,13 +126,13 @@ impl hyper::server::accept::Accept for SmolListener {
|
|||
/// A TCP or TCP+TLS connection.
|
||||
enum SmolStream {
|
||||
/// A plain TCP connection.
|
||||
Plain(TcpStream),
|
||||
Plain(Async<TcpStream>),
|
||||
|
||||
/// A TCP connection secured by TLS.
|
||||
Tls(TlsStream<TcpStream>),
|
||||
Tls(TlsStream<Async<TcpStream>>),
|
||||
|
||||
/// A TCP connection that is in process of getting secured by TLS.
|
||||
Handshake(future::BoxFuture<'static, io::Result<TlsStream<TcpStream>>>),
|
||||
Handshake(future::BoxFuture<'static, io::Result<TlsStream<Async<TcpStream>>>>),
|
||||
}
|
||||
|
||||
impl hyper::client::connect::Connection for SmolStream {
|
||||
|
@ -185,7 +189,7 @@ impl tokio::io::AsyncWrite for SmolStream {
|
|||
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
match &mut *self {
|
||||
SmolStream::Plain(s) => {
|
||||
s.shutdown(Shutdown::Write)?;
|
||||
s.get_ref().shutdown(Shutdown::Write)?;
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
SmolStream::Tls(s) => Pin::new(s).poll_close(cx),
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
//! cargo run --example simple-client
|
||||
//! ```
|
||||
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
|
||||
use anyhow::{bail, Context as _, Result};
|
||||
use async_net::TcpStream;
|
||||
use blocking::block_on;
|
||||
use async_io::Async;
|
||||
use blocking::{block_on, unblock};
|
||||
use futures::prelude::*;
|
||||
use url::Url;
|
||||
|
||||
|
@ -31,7 +33,13 @@ async fn fetch(addr: &str) -> Result<Vec<u8>> {
|
|||
);
|
||||
|
||||
// Connect to the host.
|
||||
let mut stream = TcpStream::connect(format!("{}:{}", host, port)).await?;
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
let mut stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
|
||||
// Send the request and wait for the response.
|
||||
let mut resp = Vec::new();
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
//!
|
||||
//! Refer to `README.md` to see how to the TLS certificate was generated.
|
||||
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
|
||||
use anyhow::Result;
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Identity, TlsAcceptor};
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use blocking::block_on;
|
||||
use futures::prelude::*;
|
||||
use smol::Task;
|
||||
|
@ -29,14 +31,14 @@ Content-Length: 47
|
|||
"#;
|
||||
|
||||
/// Reads a request from the client and sends it a response.
|
||||
async fn serve(mut stream: TcpStream, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
async fn serve(mut stream: Async<TcpStream>, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
match tls {
|
||||
None => {
|
||||
println!("Serving http://{}", stream.local_addr()?);
|
||||
println!("Serving http://{}", stream.get_ref().local_addr()?);
|
||||
stream.write_all(RESPONSE).await?;
|
||||
}
|
||||
Some(tls) => {
|
||||
println!("Serving https://{}", stream.local_addr()?);
|
||||
println!("Serving https://{}", stream.get_ref().local_addr()?);
|
||||
|
||||
// In case of HTTPS, establish a secure TLS connection first.
|
||||
match tls.accept(stream).await {
|
||||
|
@ -53,11 +55,11 @@ async fn serve(mut stream: TcpStream, tls: Option<TlsAcceptor>) -> Result<()> {
|
|||
}
|
||||
|
||||
/// Listens for incoming connections and serves them.
|
||||
async fn listen(listener: TcpListener, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
// Display the full host address.
|
||||
match &tls {
|
||||
None => println!("Listening on http://{}", listener.local_addr()?),
|
||||
Some(_) => println!("Listening on https://{}", listener.local_addr()?),
|
||||
None => println!("Listening on http://{}", listener.get_ref().local_addr()?),
|
||||
Some(_) => println!("Listening on https://{}", listener.get_ref().local_addr()?),
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -82,8 +84,11 @@ fn main() -> Result<()> {
|
|||
|
||||
// Start HTTP and HTTPS servers.
|
||||
block_on(async {
|
||||
let http = listen(TcpListener::bind("127.0.0.1:8000").await?, None);
|
||||
let https = listen(TcpListener::bind("127.0.0.1:8001").await?, Some(tls));
|
||||
let http = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?, None);
|
||||
let https = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(http, https).await?;
|
||||
Ok(())
|
||||
})
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
//! cargo run --example tcp-client
|
||||
//! ```
|
||||
|
||||
use async_net::TcpStream;
|
||||
use std::net::TcpStream;
|
||||
|
||||
use async_io::Async;
|
||||
use blocking::{block_on, Unblock};
|
||||
use futures::io;
|
||||
use futures::prelude::*;
|
||||
|
@ -24,8 +26,8 @@ fn main() -> io::Result<()> {
|
|||
let mut stdout = Unblock::new(std::io::stdout());
|
||||
|
||||
// Connect to the server.
|
||||
let stream = TcpStream::connect("127.0.0.1:7000").await?;
|
||||
println!("Connected to {}", stream.peer_addr()?);
|
||||
let stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 7000)).await?;
|
||||
println!("Connected to {}", stream.get_ref().peer_addr()?);
|
||||
println!("Type a message and hit enter!\n");
|
||||
|
||||
// Pipe messages from stdin to the server and pipe messages from the server to stdout.
|
||||
|
|
|
@ -12,22 +12,24 @@
|
|||
//! cargo run --example tcp-client
|
||||
//! ```
|
||||
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
|
||||
use async_io::Async;
|
||||
use blocking::block_on;
|
||||
use futures::io;
|
||||
use smol::Task;
|
||||
|
||||
/// Echoes messages from the client back to it.
|
||||
async fn echo(mut stream: TcpStream) -> io::Result<()> {
|
||||
io::copy(stream.clone(), &mut stream).await?;
|
||||
async fn echo(stream: Async<TcpStream>) -> io::Result<()> {
|
||||
io::copy(&stream, &mut &stream).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
block_on(async {
|
||||
// Create a listener.
|
||||
let listener = TcpListener::bind("127.0.0.1:7000").await?;
|
||||
println!("Listening on {}", listener.local_addr()?);
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 7000))?;
|
||||
println!("Listening on {}", listener.get_ref().local_addr()?);
|
||||
println!("Now start a TCP client.");
|
||||
|
||||
// Accept clients in a loop.
|
||||
|
|
|
@ -12,9 +12,11 @@
|
|||
//! cargo run --example tls-client
|
||||
//! ```
|
||||
|
||||
use std::net::TcpStream;
|
||||
|
||||
use anyhow::Result;
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Certificate, TlsConnector};
|
||||
use async_net::TcpStream;
|
||||
use blocking::{block_on, Unblock};
|
||||
use futures::io;
|
||||
use futures::prelude::*;
|
||||
|
@ -31,9 +33,9 @@ fn main() -> Result<()> {
|
|||
let mut stdout = Unblock::new(std::io::stdout());
|
||||
|
||||
// Connect to the server.
|
||||
let stream = TcpStream::connect("127.0.0.1:7001").await?;
|
||||
let stream = Async::<TcpStream>::connect(([127, 0, 0, 1], 7001)).await?;
|
||||
let stream = tls.connect("127.0.0.1", stream).await?;
|
||||
println!("Connected to {}", stream.get_ref().peer_addr()?);
|
||||
println!("Connected to {}", stream.get_ref().get_ref().peer_addr()?);
|
||||
println!("Type a message and hit enter!\n");
|
||||
|
||||
// Pipe messages from stdin to the server and pipe messages from the server to stdout.
|
||||
|
|
|
@ -12,15 +12,17 @@
|
|||
//! cargo run --example tls-client
|
||||
//! ```
|
||||
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
|
||||
use anyhow::Result;
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use blocking::block_on;
|
||||
use futures::io;
|
||||
use smol::Task;
|
||||
|
||||
/// Echoes messages from the client back to it.
|
||||
async fn echo(stream: TlsStream<TcpStream>) -> Result<()> {
|
||||
async fn echo(stream: TlsStream<Async<TcpStream>>) -> Result<()> {
|
||||
let stream = async_dup::Mutex::new(stream);
|
||||
io::copy(&stream, &mut &stream).await?;
|
||||
Ok(())
|
||||
|
@ -33,15 +35,18 @@ fn main() -> Result<()> {
|
|||
|
||||
block_on(async {
|
||||
// Create a listener.
|
||||
let listener = TcpListener::bind("127.0.0.1:7001").await?;
|
||||
println!("Listening on {}", listener.local_addr()?);
|
||||
let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 7001))?;
|
||||
println!("Listening on {}", listener.get_ref().local_addr()?);
|
||||
println!("Now start a TLS client.");
|
||||
|
||||
// Accept clients in a loop.
|
||||
loop {
|
||||
let (stream, _) = listener.accept().await?;
|
||||
let stream = tls.accept(stream).await?;
|
||||
println!("Accepted client: {}", stream.get_ref().peer_addr()?);
|
||||
println!(
|
||||
"Accepted client: {}",
|
||||
stream.get_ref().get_ref().peer_addr()?
|
||||
);
|
||||
|
||||
// Spawn a task that echoes messages from the client back to it.
|
||||
Task::spawn(echo(stream)).detach();
|
||||
|
|
|
@ -12,14 +12,15 @@
|
|||
//! cargo run --example websocket-client
|
||||
//! ```
|
||||
|
||||
use std::net::{TcpStream, ToSocketAddrs};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::{bail, Context as _, Result};
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Certificate, TlsConnector, TlsStream};
|
||||
use async_net::TcpStream;
|
||||
use async_tungstenite::WebSocketStream;
|
||||
use blocking::block_on;
|
||||
use blocking::{block_on, unblock};
|
||||
use futures::prelude::*;
|
||||
use tungstenite::handshake::client::Response;
|
||||
use tungstenite::Message;
|
||||
|
@ -32,16 +33,24 @@ async fn connect(addr: &str, tls: TlsConnector) -> Result<(WsStream, Response)>
|
|||
let host = url.host_str().context("cannot parse host")?.to_string();
|
||||
let port = url.port_or_known_default().context("cannot guess port")?;
|
||||
|
||||
// Resolve the address.
|
||||
let socket_addr = {
|
||||
let host = host.clone();
|
||||
unblock!((host.as_str(), port).to_socket_addrs())?
|
||||
.next()
|
||||
.context("cannot resolve address")?
|
||||
};
|
||||
|
||||
// Connect to the address.
|
||||
match url.scheme() {
|
||||
"ws" => {
|
||||
let stream = TcpStream::connect(format!("{}:{}", host, port)).await?;
|
||||
let stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
let (stream, resp) = async_tungstenite::client_async(addr, stream).await?;
|
||||
Ok((WsStream::Plain(stream), resp))
|
||||
}
|
||||
"wss" => {
|
||||
// In case of WSS, establish a secure TLS connection first.
|
||||
let stream = TcpStream::connect(format!("{}:{}", host, port)).await?;
|
||||
let stream = Async::<TcpStream>::connect(socket_addr).await?;
|
||||
let stream = tls.connect(host, stream).await?;
|
||||
let (stream, resp) = async_tungstenite::client_async(addr, stream).await?;
|
||||
Ok((WsStream::Tls(stream), resp))
|
||||
|
@ -72,10 +81,10 @@ fn main() -> Result<()> {
|
|||
/// A WebSocket or WebSocket+TLS connection.
|
||||
enum WsStream {
|
||||
/// A plain WebSocket connection.
|
||||
Plain(WebSocketStream<TcpStream>),
|
||||
Plain(WebSocketStream<Async<TcpStream>>),
|
||||
|
||||
/// A WebSocket connection secured by TLS.
|
||||
Tls(WebSocketStream<TlsStream<TcpStream>>),
|
||||
Tls(WebSocketStream<TlsStream<Async<TcpStream>>>),
|
||||
}
|
||||
|
||||
impl Sink<Message> for WsStream {
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
//! cargo run --example websocket-client
|
||||
//! ```
|
||||
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use async_io::Async;
|
||||
use async_native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use async_net::{TcpListener, TcpStream};
|
||||
use async_tungstenite::WebSocketStream;
|
||||
use blocking::block_on;
|
||||
use futures::prelude::*;
|
||||
|
@ -32,17 +33,17 @@ async fn echo(mut stream: WsStream) -> Result<()> {
|
|||
}
|
||||
|
||||
/// Listens for incoming connections and serves them.
|
||||
async fn listen(listener: TcpListener, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
async fn listen(listener: Async<TcpListener>, tls: Option<TlsAcceptor>) -> Result<()> {
|
||||
let host = match &tls {
|
||||
None => format!("ws://{}", listener.local_addr()?),
|
||||
Some(_) => format!("wss://{}", listener.local_addr()?),
|
||||
None => format!("ws://{}", listener.get_ref().local_addr()?),
|
||||
Some(_) => format!("wss://{}", listener.get_ref().local_addr()?),
|
||||
};
|
||||
println!("Listening on {}", host);
|
||||
|
||||
loop {
|
||||
// Accept the next connection.
|
||||
let (stream, _) = listener.accept().await?;
|
||||
println!("Accepted client: {}", stream.peer_addr()?);
|
||||
println!("Accepted client: {}", stream.get_ref().peer_addr()?);
|
||||
|
||||
match &tls {
|
||||
None => {
|
||||
|
@ -66,8 +67,11 @@ fn main() -> Result<()> {
|
|||
|
||||
// Start WS and WSS servers.
|
||||
block_on(async {
|
||||
let ws = listen(TcpListener::bind("127.0.0.1:9000").await?, None);
|
||||
let wss = listen(TcpListener::bind("127.0.0.1:9001").await?, Some(tls));
|
||||
let ws = listen(Async::<TcpListener>::bind(([127, 0, 0, 1], 9000))?, None);
|
||||
let wss = listen(
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 9001))?,
|
||||
Some(tls),
|
||||
);
|
||||
future::try_join(ws, wss).await?;
|
||||
Ok(())
|
||||
})
|
||||
|
@ -76,10 +80,10 @@ fn main() -> Result<()> {
|
|||
/// A WebSocket or WebSocket+TLS connection.
|
||||
enum WsStream {
|
||||
/// A plain WebSocket connection.
|
||||
Plain(WebSocketStream<TcpStream>),
|
||||
Plain(WebSocketStream<Async<TcpStream>>),
|
||||
|
||||
/// A WebSocket connection secured by TLS.
|
||||
Tls(WebSocketStream<TlsStream<TcpStream>>),
|
||||
Tls(WebSocketStream<TlsStream<Async<TcpStream>>>),
|
||||
}
|
||||
|
||||
impl Sink<Message> for WsStream {
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
//!
|
||||
//! * For async I/O and timers, use [`async-io`].
|
||||
//! * For higher-level networking primitives, use [`async-net`].
|
||||
//! * For executors, use [`multitask`].
|
||||
//! * To call blocking code from async code or the other way around, use [`blocking`].
|
||||
//!
|
||||
//! [`async-io`]: https://docs.rs/async-io
|
||||
//! [`async-net`]: https://docs.rs/async-net
|
||||
//! [`blocking`]: https://docs.rs/blocking
|
||||
//! [`multitask`]: https://docs.rs/multitask
|
||||
//! [`tokio`]: https://docs.rs/tokio
|
||||
//!
|
||||
//! # TCP server
|
||||
|
@ -20,14 +22,15 @@
|
|||
//! A simple TCP server that prints messages received from clients:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use async_net::TcpListener;
|
||||
//! use async_io::Async;
|
||||
//! use blocking::{block_on, Unblock};
|
||||
//! use smol::Task;
|
||||
//! use std::net::TcpListener;
|
||||
//!
|
||||
//! fn main() -> std::io::Result<()> {
|
||||
//! block_on(async {
|
||||
//! // Start listening on port 9000.
|
||||
//! let listener = TcpListener::bind("127.0.0.1:9000").await?;
|
||||
//! let listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 9000))?;
|
||||
//!
|
||||
//! loop {
|
||||
//! // Accept a new client.
|
||||
|
|
Loading…
Reference in New Issue