#server #backpressure #async #listen #accept #helper

async-listen

使用 async-std 在 Rust 中编写生产级服务器的各种辅助工具

7 个版本

0.2.1 2020 年 6 月 17 日
0.2.0 2020 年 1 月 19 日
0.1.5 2020 年 1 月 14 日

4#accept

Download history 758/week @ 2024-03-15 917/week @ 2024-03-22 1007/week @ 2024-03-29 635/week @ 2024-04-05 983/week @ 2024-04-12 1309/week @ 2024-04-19 1082/week @ 2024-04-26 724/week @ 2024-05-03 660/week @ 2024-05-10 763/week @ 2024-05-17 695/week @ 2024-05-24 597/week @ 2024-05-31 665/week @ 2024-06-07 523/week @ 2024-06-14 535/week @ 2024-06-21 424/week @ 2024-06-28

2,266 每月下载次数
用于 vented

MIT/Apache

59KB
813

Async Listen

该包包含使用 async-std 在 Rust 中编写生产级服务器的各种辅助工具。

文档 | Github | Crate

功能

  • 接受循环中的错误处理
  • 限制传入连接的数量

许可证

许可协议为以下之一:

贡献

除非您明确声明,否则您有意提交以包含在作品中的任何贡献,根据 Apache-2.0 许可协议定义,应按上述方式双许可,不得附加任何额外条款或条件。


lib.rs:

Async Listen

该包包含使用 async-std 在 Rust 中编写生产级服务器的各种辅助工具。

文档 | Github | Crate

实用工具

低级实用工具

示例

以下是一个相当详细的示例,演示了以下内容:

  • 背压(同时连接数的限制)
  • 错误处理
  • Tcp 和 Unix 套接字的统一
use std::env::args;
use std::error::Error;
use std::fs::remove_file;
use std::io;
use std::time::Duration;

use async_std::task;
use async_std::net::TcpListener;
use async_std::prelude::*;

use async_listen::{ListenExt, ByteStream, backpressure, error_hint};


fn main() -> Result<(), Box<dyn Error>> {
    let (_, bp) = backpressure::new(10);
    #[cfg(unix)] {
        use async_std::os::unix::net::UnixListener;

        if args().any(|x| x == "--unix") {
            remove_file("./example.sock").ok();
            return task::block_on(async {
                let listener = UnixListener::bind("./example.sock").await?;
                eprintln!("Accepting connections on ./example.sock");
                let mut incoming = listener.incoming()
                    .log_warnings(log_accept_error)
                    .handle_errors(Duration::from_millis(500))
                    .backpressure_wrapper(bp);
                while let Some(stream) = incoming.next().await {
                    task::spawn(connection_loop(stream));
                }
                Ok(())
            });
        }
    }
    task::block_on(async {
        let listener = TcpListener::bind("localhost:8080").await?;
        eprintln!("Accepting connections on localhost:8080");
        let mut incoming = listener.incoming()
            .log_warnings(log_accept_error)
            .handle_errors(Duration::from_millis(500))
            .backpressure_wrapper(bp);
        while let Some(stream) = incoming.next().await {
            task::spawn(async {
                if let Err(e) = connection_loop(stream).await {
                    eprintln!("Error: {}", e);
                }
            });
        }
        Ok(())
    })
}

async fn connection_loop(mut stream: ByteStream) -> Result<(), io::Error> {
    println!("Connected from {}", stream.peer_addr()?);
    task::sleep(Duration::from_secs(5)).await;
    stream.write_all("hello\n".as_bytes()).await?;
    Ok(())
}

fn log_accept_error(e: &io::Error) {
    eprintln!("Accept error: {}. Sleeping 0.5s. {}", e, error_hint(&e));
}

依赖关系

~4–14MB
~164K SLoC