1
0
mirror of https://github.com/actix/actix-website synced 2025-02-24 21:13:20 +01:00

convert server examples

This commit is contained in:
Nikolay Kim 2018-05-23 20:39:15 -07:00
parent d4e2aa8ae9
commit d27ab00b71
17 changed files with 185 additions and 211 deletions

View File

@ -1,42 +0,0 @@
[package]
name = "actix-website"
version = "0.6.0"
authors = ["Actix Project and Contributors"]
readme = "README.md"
keywords = ["http", "web", "framework", "async", "futures"]
homepage = "https://github.com/actix/actix-website/"
repository = "https://github.com/actix/actix-website.git"
documentation = "https://docs.rs/actix-website/"
categories = ["network-programming", "asynchronous",
"web-programming::http-server",
"web-programming::http-client",
"web-programming::websocket"]
license = "MIT/Apache-2.0"
exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
[lib]
src="src/lib.rs"
crate-type = ["dylib"]
[dependencies]
actix = "^0.5.6"
actix-web = "^0.6"
flate2 = "1.0"
serde = "1.0"
serde_json = "1.0"
serde_urlencoded = "0.5"
# io
bytes = "0.4"
futures = "0.1"
tokio-io = "0.1"
tokio-core = "0.1"
http = "0.1"
[dev-dependencies]
env_logger = "0.5"
serde_derive = "1.0"
[build-dependencies]
futures = "0.1"

View File

@ -21,22 +21,7 @@ To start the http server, one of the start methods.
`HttpServer` is an actix actor. It must be initialized within a properly configured actix system: `HttpServer` is an actix actor. It must be initialized within a properly configured actix system:
```rust {{< include-example example="server" section="main" >}}
use actix_web::{server::HttpServer, App, HttpResponse};
fn main() {
let sys = actix::System::new("guide");
HttpServer::new(|| {
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
})
.bind("127.0.0.1:59080").unwrap()
.start();
let _ = sys.run();
}
```
> It is possible to start a server in a separate thread with the `run()` method. In that > It is possible to start a server in a separate thread with the `run()` method. In that
> case the server spawns a new thread and creates a new actix system in it. To stop > case the server spawns a new thread and creates a new actix system in it. To stop
@ -50,32 +35,7 @@ address of the started http server. It accepts several messages:
- `ResumeServer` - Resume accepting incoming connections - `ResumeServer` - Resume accepting incoming connections
- `StopServer` - Stop incoming connection processing, stop all workers and exit - `StopServer` - Stop incoming connection processing, stop all workers and exit
```rust {{< include-example example="server" file="signals.rs" section="signals" >}}
use std::thread;
use std::sync::mpsc;
use actix_web::{server, App, HttpResponse};
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let sys = actix::System::new("http-server");
let addr = server::new(|| {
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
})
.bind("127.0.0.1:0").expect("Can not bind to 127.0.0.1:0")
.shutdown_timeout(60) // <- Set shutdown timeout to 60 seconds
.start();
let _ = tx.send(addr);
let _ = sys.run();
});
let addr = rx.recv().unwrap();
let _ = addr.send(
server::StopServer{graceful:true}).wait(); // <- Send `StopServer` message to server.
}
```
## Multi-threading ## Multi-threading
@ -83,17 +43,7 @@ fn main() {
this number is equal to number of logical CPUs in the system. This number this number is equal to number of logical CPUs in the system. This number
can be overridden with the `HttpServer::workers()` method. can be overridden with the `HttpServer::workers()` method.
```rust {{< include-example example="server" file="workers.rs" section="workers" >}}
use actix_web::{App, HttpResponse, server::HttpServer};
fn main() {
HttpServer::new(|| {
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
})
.workers(4); // <- Start 4 workers
}
```
The server creates a separate application instance for each created worker. Application state The server creates a separate application instance for each created worker. Application state
is not shared between threads. To share state, `Arc` could be used. is not shared between threads. To share state, `Arc` could be used.
@ -111,24 +61,7 @@ for `native-tls` integration and `alpn` is for `openssl`.
actix-web = { version = "{{< actix-version "actix-web" >}}", features = ["alpn"] } actix-web = { version = "{{< actix-version "actix-web" >}}", features = ["alpn"] }
``` ```
```rust {{< include-example example="server" file="ssl.rs" section="ssl" >}}
use std::fs::File;
use actix_web::*;
fn main() {
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_private_key_file("key.pem", SslFiletype::PEM).unwrap();
builder.set_certificate_chain_file("cert.pem").unwrap();
server::new(|| {
App::new()
.resource("/index.html", |r| r.f(index))
})
.bind_ssl("127.0.0.1:8080", builder).unwrap()
.serve();
}
```
> **Note**: the *HTTP/2.0* protocol requires > **Note**: the *HTTP/2.0* protocol requires
> [tls alpn](https://tools.ietf.org/html/rfc7301). > [tls alpn](https://tools.ietf.org/html/rfc7301).
@ -156,26 +89,7 @@ Actix can wait for requests on a keep-alive connection.
- `None` or `KeepAlive::Disabled` - disable *keep alive*. - `None` or `KeepAlive::Disabled` - disable *keep alive*.
- `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option. - `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option.
```rust {{< include-example example="server" file="ka.rs" section="ka" >}}
use actix_web::{server, App, HttpResponse};
fn main() {
server::new(||
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(75); // <- Set keep-alive to 75 seconds
server::new(||
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option.
server::new(||
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(None); // <- Disable keep-alive
}
```
If the first option is selected, then *keep alive* state is If the first option is selected, then *keep alive* state is
calculated based on the response's *connection-type*. By default calculated based on the response's *connection-type*. By default
@ -186,16 +100,7 @@ defined by the request's http version.
*Connection type* can be change with `HttpResponseBuilder::connection_type()` method. *Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
```rust {{< include-example example="server" file="ka_tp.rs" section="example" >}}
use actix_web::{HttpRequest, HttpResponse, http};
fn index(req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.connection_type(http::ConnectionType::Close) // <- Close connection
.force_close() // <- Alternative method
.finish()
}
```
## Graceful shutdown ## Graceful shutdown

View File

@ -2,4 +2,5 @@
members = [ members = [
"application", "application",
"getting-started", "getting-started",
"server",
] ]

View File

@ -1,6 +1,7 @@
[package] [package]
name = "application" name = "application"
version = "0.1.0" version = "0.6.0"
workspace = "../"
[dependencies] [dependencies]
actix-web = "0.6" actix-web = "0.6"

View File

@ -1,16 +1,16 @@
#![allow(unused)] #![allow(unused)]
extern crate actix_web; extern crate actix_web;
use actix_web::{App, Responder, HttpRequest, HttpResponse, server, http::Method}; use actix_web::{http::Method, server, App, HttpRequest, HttpResponse, Responder};
mod state; mod state;
fn make_app() { fn make_app() {
// <make_app> // <make_app>
fn index(req: HttpRequest) -> impl Responder { fn index(req: HttpRequest) -> impl Responder {
"Hello world!" "Hello world!"
} }
let app = App::new() let app = App::new()
.prefix("/app") .prefix("/app")
.resource("/index.html", |r| r.method(Method::GET).f(index)) .resource("/index.html", |r| r.method(Method::GET).f(index))
.finish() .finish()
@ -19,18 +19,19 @@ let app = App::new()
} }
fn run_server() { fn run_server() {
// <run_server> // <run_server>
let server = server::new(|| vec![ let server = server::new(|| {
App::new() vec![
.prefix("/app1") App::new()
.resource("/", |r| r.f(|r| HttpResponse::Ok())), .prefix("/app1")
App::new() .resource("/", |r| r.f(|r| HttpResponse::Ok())),
.prefix("/app2") App::new()
.resource("/", |r| r.f(|r| HttpResponse::Ok())), .prefix("/app2")
App::new() .resource("/", |r| r.f(|r| HttpResponse::Ok())),
.resource("/", |r| r.f(|r| HttpResponse::Ok())), App::new().resource("/", |r| r.f(|r| HttpResponse::Ok())),
]); ]
// </run_server> });
// </run_server>
} }
fn main() { fn main() {

View File

@ -1,6 +1,6 @@
// <setup> // <setup>
use actix_web::{http, App, HttpRequest};
use std::cell::Cell; use std::cell::Cell;
use actix_web::{App, HttpRequest, http};
// This struct represents state // This struct represents state
struct AppState { struct AppState {
@ -9,51 +9,48 @@ struct AppState {
fn index(req: HttpRequest<AppState>) -> String { fn index(req: HttpRequest<AppState>) -> String {
let count = req.state().counter.get() + 1; // <- get count let count = req.state().counter.get() + 1; // <- get count
req.state().counter.set(count); // <- store new count in state req.state().counter.set(count); // <- store new count in state
format!("Request number: {}", count) // <- response with count format!("Request number: {}", count) // <- response with count
} }
// </setup> // </setup>
fn make_app() { fn make_app() {
// <make_app>
// <make_app> App::with_state(AppState { counter: Cell::new(0) })
App::with_state(AppState { counter: Cell::new(0) })
.resource("/", |r| r.method(http::Method::GET).f(index)) .resource("/", |r| r.method(http::Method::GET).f(index))
.finish() .finish()
// </make_app> // </make_app>
; ;
} }
use std::thread;
use actix_web::{server, HttpResponse}; use actix_web::{server, HttpResponse};
use std::thread;
fn combine() { fn combine() {
thread::spawn(|| { thread::spawn(|| {
// <combine> // <combine>
struct State1; struct State1;
struct State2; struct State2;
fn main() { fn main() {
server::new(|| { server::new(|| {
vec![ vec![
App::with_state(State1) App::with_state(State1)
.prefix("/app1") .prefix("/app1")
.resource("/", |r| r.f(|r| HttpResponse::Ok())) .resource("/", |r| r.f(|r| HttpResponse::Ok()))
.boxed(), .boxed(),
App::with_state(State2) App::with_state(State2)
.prefix("/app2") .prefix("/app2")
.resource("/", |r| r.f(|r| HttpResponse::Ok())) .resource("/", |r| r.f(|r| HttpResponse::Ok()))
.boxed() .boxed(),
] ]
}) }).bind("127.0.0.1:8080")
.bind("127.0.0.1:8080").unwrap() .unwrap()
.run() .run()
} }
// </combine> // </combine>
}); });
} }
pub fn test() { pub fn test() {

View File

@ -1,6 +1,7 @@
[package] [package]
name = "getting-started" name = "getting-started"
version = "0.1.0" version = "0.6.0"
workspace = "../"
[dependencies] [dependencies]
actix-web = "0.6" actix-web = "0.6"

View File

@ -1,6 +1,6 @@
// <setup> // <setup>
extern crate actix_web; extern crate actix_web;
use actix_web::{HttpRequest, App, server}; use actix_web::{server, App, HttpRequest};
fn index(_req: HttpRequest) -> &'static str { fn index(_req: HttpRequest) -> &'static str {
"Hello world!" "Hello world!"
@ -8,11 +8,9 @@ fn index(_req: HttpRequest) -> &'static str {
// </setup> // </setup>
// <main> // <main>
fn main() { fn main() {
server::new(|| { server::new(|| App::new().resource("/", |r| r.f(index)))
App::new() .bind("127.0.0.1:8088")
.resource("/", |r| r.f(index)) .unwrap()
}) .run();
.bind("127.0.0.1:8088").unwrap()
.run();
} }
// </main> // </main>

5
examples/rustfmt.toml Normal file
View File

@ -0,0 +1,5 @@
max_width = 89
reorder_imports = true
wrap_comments = true
fn_args_density = "Compressed"
#use_small_heuristics = false

View File

@ -0,0 +1,10 @@
[package]
name = "server"
version = "0.6.0"
workspace = "../"
[dependencies]
actix = "0.5"
actix-web = { version="0.6", features=["alpn"] }
futures = "0.1"
openssl = "0.10"

14
examples/server/src/ka.rs Normal file
View File

@ -0,0 +1,14 @@
// <ka>
use actix_web::{server, App, HttpResponse};
fn main() {
server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(75); // <- Set keep-alive to 75 seconds
server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(server::KeepAlive::Tcp(75)); // <- Use `SO_KEEPALIVE` socket option.
server::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok())))
.keep_alive(None); // <- Disable keep-alive
}
// </ka>

View File

@ -0,0 +1,10 @@
// <example>
use actix_web::{http, HttpRequest, HttpResponse};
fn index(req: HttpRequest) -> HttpResponse {
HttpResponse::Ok()
.connection_type(http::ConnectionType::Close) // <- Close connection
.force_close() // <- Alternative method
.finish()
}
// </example>

View File

@ -0,0 +1,25 @@
extern crate actix;
extern crate actix_web;
extern crate futures;
extern crate openssl;
mod ka;
mod ka_tp;
mod signals;
mod ssl;
mod workers;
// <main>
use actix_web::{server::HttpServer, App, HttpResponse};
fn main() {
let sys = actix::System::new("guide");
HttpServer::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok())))
.bind("127.0.0.1:59080")
.unwrap()
.start();
let _ = sys.run();
}
// </main>

View File

@ -0,0 +1,28 @@
use actix;
use futures::Future;
// <signals>
use actix_web::{server, App, HttpResponse};
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let sys = actix::System::new("http-server");
let addr = server::new(|| {
App::new()
.resource("/", |r| r.f(|_| HttpResponse::Ok()))
})
.bind("127.0.0.1:0").expect("Can not bind to 127.0.0.1:0")
.shutdown_timeout(60) // <- Set shutdown timeout to 60 seconds
.start();
let _ = tx.send(addr);
let _ = sys.run();
});
let addr = rx.recv().unwrap();
let _ = addr.send(server::StopServer { graceful: true }).wait(); // <- Send `StopServer` message to server.
}
// </signals>

View File

@ -0,0 +1,22 @@
// <ssl>
use actix_web::{server, App, HttpRequest, Responder};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
fn index(req: HttpRequest) -> impl Responder {
"Welcome!"
}
fn main() {
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder
.set_private_key_file("key.pem", SslFiletype::PEM)
.unwrap();
builder.set_certificate_chain_file("cert.pem").unwrap();
server::new(|| App::new().resource("/index.html", |r| r.f(index)))
.bind_ssl("127.0.0.1:8080", builder)
.unwrap()
.run();
}
// </ssl>

View File

@ -0,0 +1,8 @@
// <workers>
use actix_web::{server::HttpServer, App, HttpResponse};
fn main() {
HttpServer::new(|| App::new().resource("/", |r| r.f(|_| HttpResponse::Ok())))
.workers(4); // <- Start 4 workers
}
// </workers>

View File

@ -1,10 +0,0 @@
extern crate http;
extern crate actix;
extern crate actix_web;
extern crate futures;
extern crate tokio_io;
extern crate tokio_core;
pub fn test() {
println!("test");
}