Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve doc.rs documentation #166

Merged
merged 26 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0ee6a55
doc(engineio): documentation reworked
Totodore Nov 13, 2023
51949d6
doc(socketio): documentation wip
Totodore Nov 13, 2023
9ca9d2c
doc(socketio): documentation wip
Totodore Nov 13, 2023
1a1ba09
fix(socketio): `AckResponse` imports
Totodore Nov 15, 2023
e34369d
fix(test): `DisconnectReason` imports
Totodore Nov 15, 2023
a262b38
chore(deps): export common packages to workspace
Totodore Nov 15, 2023
bf93944
doc(engineio): fix doctests
Totodore Nov 15, 2023
801c268
doc(socketio): fix doctests
Totodore Nov 15, 2023
2349309
Merge branch 'main' into doc-improve-doc
Totodore Nov 15, 2023
e62054a
doc(engineio): fix docs
Totodore Nov 15, 2023
5d90d32
doc(socketio): fix docs
Totodore Nov 15, 2023
903ddc7
doc: feature flag
Totodore Nov 15, 2023
c690063
doc(socketio): rework doc
Totodore Nov 16, 2023
6b4028f
doc(socketio/handler): add custom extractor example
Totodore Nov 21, 2023
cb27397
Merge remote-tracking branch 'origin/HEAD' into doc-improve-doc
Totodore Nov 21, 2023
7a77f51
Merge branch 'main' into doc-improve-doc
Totodore Nov 21, 2023
31ce6c7
doc(socketio/socket): fix doctest
Totodore Nov 21, 2023
6e5633f
Merge branch 'main' into doc-improve-doc
Totodore Nov 21, 2023
10be85d
doc(socketio): improve index documentation
Totodore Nov 21, 2023
d83bb71
Merge branch 'main' into doc-improve-doc
Totodore Nov 22, 2023
f5a7752
chore(socketio/socket): remove `DisconnectCallback` public type
Totodore Nov 22, 2023
7ff7edc
doc(socketio): minor improvements
Totodore Nov 22, 2023
e25cd7f
doc(socketio): adapters
Totodore Nov 22, 2023
896ce8e
doc(socketio): io documentation
Totodore Nov 22, 2023
b6403b0
doc(socketio): hide imports in example
Totodore Nov 22, 2023
dde8b68
doc(socketio): typo
Totodore Nov 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ http-body = "0.4.5"
thiserror = "1.0.40"
tracing = "0.1.37"
itoa = "1.0.9"

tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
hyper = "0.14.25"
axum = "0.6.20"
warp = "0.3.6"
salvo = { version = "0.58.2", features = ["tower-compat"] }

# Hyper v0.1
http-body-v1 = { package = "http-body", version = "1.0.0-rc.2" }
Expand Down
7 changes: 2 additions & 5 deletions e2e/engineioxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ engineioxide = { path = "../../engineioxide", default-features = false, features
"tracing",
"hyper-v1",
] }
hyper-v1 = { package = "hyper", version = "1.0.0-rc.4", features = [
"server",
"http1",
] }
hyper-v1 = { workspace = true, features = ["server", "http1"] }
hyper-util = { git = "https://github.com/hyperium/hyper-util.git", version = "0" }
hyper = { version = "0.14.26", features = ["server", "http1", "tcp"] }
hyper = { workspace = true, features = ["server", "http1", "tcp"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tracing-subscriber.workspace = true
tracing.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion e2e/socketioxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ publish = false
socketioxide = { path = "../../socketioxide", default-features = false, features = [
"tracing",
] }
hyper = { version = "0.14.26", features = ["server", "http1", "tcp"] }
hyper = { workspace = true, features = ["server", "http1", "tcp"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tracing-subscriber.workspace = true
tracing.workspace = true
Expand Down
15 changes: 12 additions & 3 deletions engineioxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ keywords.workspace = true
categories.workspace = true
license.workspace = true

# docs.rs-specific configuration
[package.metadata.docs.rs]
features = ["v3", "hyper-v1"]
# Special configuration for docs.rs build
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
futures.workspace = true
http.workspace = true
Expand All @@ -20,10 +26,10 @@ serde_json.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["rt", "time"] }
tower.workspace = true
hyper.workspace = true

base64 = "0.21.0"
bytes = "1.4.0"
hyper = "0.14.25"
pin-project = "1.0.12"
tokio-tungstenite = "0.20.1"
rand = "0.8.5"
Expand All @@ -41,15 +47,18 @@ http-body-v1 = { workspace = true, optional = true }

[dev-dependencies]
tokio = { workspace = true, features = ["macros", "parking_lot"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
hyper = { version = "0.14.25", features = [
tracing-subscriber.workspace = true
hyper = { workspace = true, features = [
"http1",
"http2",
"server",
"stream",
"runtime",
"client",
] }
warp.workspace = true
axum.workspace = true
salvo.workspace = true

[features]
v3 = ["memchr", "unicode-segmentation"]
Expand Down
141 changes: 93 additions & 48 deletions engineioxide/Readme.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,113 @@
## Engineioxide does the heavy lifting for [Socketioxide](https://docs.rs/socketioxide/latest/socketioxide/), a SocketIO server implementation in Rust which integrates with the [tower](https://docs.rs/tower/latest/tower/) stack.
### Engineioxide does the heavy lifting for [socketioxide](https://docs.rs/socketioxide/latest/socketioxide/), a socket.io server implementation in Rust which integrates with the [tower](https://docs.rs/tower/latest/tower/) stack.

### It can also be used as a standalone server for [EngineIO clients](https://github.com/socketio/engine.io-client).
You can still use engineioxide as a standalone crate to talk with an engine.io client.

### Engine.IO example echo implementation with Axum :
### Supported Protocols
You can enable support for other engine.io protocol implementations through feature flags.
The latest protocol version (v4) is enabled by default.

To add support for the `v3` protocol version, adjust your dependency configuration accordingly:

```toml
[dependencies]
# Enables the `v3` protocol (`v4` is always enabled, as it's the default).
engineioxide = { version = "0.3.0", features = ["v3"] }
```

## Feature flags :
* `v3`: Enable the engine.io v3 protocol
* `tracing`: Enable tracing logs with the `tracing` crate
* `hyper-v1`: Hyper v1 compatibility layer. For the moment most of the http crates use hyper v0

## Basic example with axum :
```rust
use engineioxide::layer::EngineIoLayer;
use engineioxide::handler::EngineIoHandler;
use engineioxide::{Socket, DisconnectReason};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use axum::routing::get;
// Global state, with axum it must be clonable
#[derive(Debug, Default, Clone)]
struct MyHandler {
user_cnt: Arc<AtomicUsize>,
}

#[derive(Clone)]
struct MyHandler;
// Socket state
#[derive(Debug, Default)]
struct SocketState {
id: Mutex<String>,
}

impl EngineIoHandler for MyHandler {
type Data = ();

fn on_connect(&self, socket: &Socket<Self>) {
println!("socket connect {}", socket.sid);
}
fn on_disconnect(&self, socket: &Socket<Self>) {
println!("socket disconnect {}", socket.sid);
}
type Data = SocketState;

fn on_message(&self, msg: String, socket: &Socket<Self>) {
println!("Ping pong message {:?}", msg);
socket.emit(msg).ok();
fn on_connect(&self, socket: Arc<Socket<SocketState>>) {
let cnt = self.user_cnt.fetch_add(1, Ordering::Relaxed) + 1;
socket.emit(cnt.to_string()).ok();
}

fn on_binary(&self, data: Vec<u8>, socket: &Socket<Self>) {
println!("Ping pong binary message {:?}", data);
socket.emit_binary(data).ok();
fn on_disconnect(&self, socket: Arc<Socket<SocketState>>, reason: DisconnectReason) {
let cnt = self.user_cnt.fetch_sub(1, Ordering::Relaxed) - 1;
socket.emit(cnt.to_string()).ok();
}
fn on_message(&self, msg: String, socket: Arc<Socket<SocketState>>) {
*socket.data.id.lock().unwrap() = msg; // bind a provided user id to a socket
}
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<SocketState>>) { }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let subscriber = FmtSubscriber::builder().finish();
tracing::subscriber::set_global_default(subscriber)?;
// Create a new engineio layer
let layer = EngineIoLayer::new(MyHandler::default());

info!("Starting server");
let app = axum::Router::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(EngineIoLayer::new(MyHandler));
let app = axum::Router::<()>::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(layer);

Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await?;
// Spawn the axum server

Ok(())
}
```

### Supported Protocols
You can enable support for other EngineIO protocol implementations through feature flags.
The latest supported protocol version is enabled by default.
#### Basic example with salvo (with the `hyper-v1` feature flag) :
```rust
use engineioxide::layer::EngineIoLayer;
use engineioxide::handler::EngineIoHandler;
use engineioxide::{Socket, DisconnectReason};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};

To add support for another protocol version, adjust your dependency configuration accordingly:
// Global state, with salvo it must be clonable
#[derive(Debug, Default, Clone)]
struct MyHandler {
user_cnt: Arc<AtomicUsize>,
}

```toml
[dependencies]
# Enables the `v3` protocol (`v4` is also implicitly enabled, as it's the default).
engineioxide = { version = "0.3.0", features = ["v3"] }
```
// Socket state
#[derive(Debug, Default)]
struct SocketState {
id: Mutex<String>,
}

To enable *a single protocol version only*, disable default features:
impl EngineIoHandler for MyHandler {
type Data = SocketState;

```toml
[dependencies]
# Enables the `v3` protocol only.
engineioxide = { version = "0.3.0", features = ["v3"], default-features = false }
```
fn on_connect(&self, socket: Arc<Socket<SocketState>>) {
let cnt = self.user_cnt.fetch_add(1, Ordering::Relaxed) + 1;
socket.emit(cnt.to_string()).ok();
}
fn on_disconnect(&self, socket: Arc<Socket<SocketState>>, reason: DisconnectReason) {
let cnt = self.user_cnt.fetch_sub(1, Ordering::Relaxed) - 1;
socket.emit(cnt.to_string()).ok();
}
fn on_message(&self, msg: String, socket: Arc<Socket<SocketState>>) {
*socket.data.id.lock().unwrap() = msg; // bind a provided user id to a socket
}
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<SocketState>>) { }
}

// Create a new engineio layer
let layer = EngineIoLayer::new(MyHandler::default())
.with_hyper_v1(); // Enable the hyper-v1 compatibility layer for salvo
// .compat(); // Enable the salvo compatibility layer

// Create a new salvo server with the given layer...
```
1 change: 1 addition & 0 deletions engineioxide/src/body/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg_attr(docsrs, doc(cfg(feature = "hyper-v1")))]
#[cfg(feature = "hyper-v1")]
pub mod request;

Expand Down
2 changes: 1 addition & 1 deletion engineioxide/src/body/request.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Custom Request Body compat struct implementation to map [`http_body_v1::Body`] to a [`http_body::Body`]
//! Only enabled with the feature flag `hyper-v1`
//!
//! Eavily inspired from : https://github.com/davidpdrsn/tower-hyper-http-body-compat
//! Eavily inspired from : [davidpdrsn/tower-hyper-http-body-compat](https://github.com/davidpdrsn/tower-hyper-http-body-compat)

use std::{
pin::Pin,
Expand Down
38 changes: 37 additions & 1 deletion engineioxide/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
//! ## Configuration for the engine.io engine & transports
//! #### Example :
//! ```rust
//! # use engineioxide::config::EngineIoConfig;
//! # use engineioxide::service::EngineIoService;
//! # use engineioxide::handler::EngineIoHandler;
//! # use std::time::Duration;
//! # use engineioxide::{Socket, DisconnectReason};
//! # use std::sync::Arc;
//! #[derive(Debug, Clone)]
//! struct MyHandler;
//!
//! impl EngineIoHandler for MyHandler {
//! type Data = ();
//! fn on_connect(&self, socket: Arc<Socket<()>>) { }
//! fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) { }
//! fn on_message(&self, msg: String, socket: Arc<Socket<()>>) { }
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<()>>) { }
//! }
//!
//! let config = EngineIoConfig::builder()
//! .ping_interval(Duration::from_millis(300)) // Set the ping_interval to 300ms
//! .ping_timeout(Duration::from_millis(200)) // Set the ping timeout to 200ms
//! .max_payload(1e6 as u64) // Set the max payload to a given size
//! .max_buffer_size(1024) // Set a custom buffer size
//! .build();
//!
//! // Create an engine io service with a custom config
//! let svc = EngineIoService::with_config(MyHandler, config);
//! ```

use std::time::Duration;

pub use crate::service::TransportType;
use crate::service::TransportType;

/// Configuration for the engine.io engine & transports
#[derive(Debug, Clone)]
pub struct EngineIoConfig {
/// The path to listen for engine.io requests on.
Expand Down Expand Up @@ -46,6 +78,7 @@ impl Default for EngineIoConfig {
}

impl EngineIoConfig {
/// Create a new builder with a default config
pub fn builder() -> EngineIoConfigBuilder {
EngineIoConfigBuilder::new()
}
Expand All @@ -56,11 +89,14 @@ impl EngineIoConfig {
self.transports & transport as u8 == transport as u8
}
}

/// Builder for [`EngineIoConfig`]
pub struct EngineIoConfigBuilder {
config: EngineIoConfig,
}

impl EngineIoConfigBuilder {
/// Create a new builder with a default config
pub fn new() -> Self {
Self {
config: EngineIoConfig::default(),
Expand Down
Loading