diff --git a/.github/workflows/bencher.yml b/.github/workflows/bencher.yml
index 51d41ded..3c44eea0 100644
--- a/.github/workflows/bencher.yml
+++ b/.github/workflows/bencher.yml
@@ -31,7 +31,6 @@ jobs:
BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
BENCHER_CMD: cargo bench --all-features
BENCHER_PROJECT: socketioxide
- RUSTFLAGS: --cfg=socketioxide_test
benchmark_pr:
if: github.event_name == 'workflow_dispatch' && github.event.pull_request.head.repo.full_name == github.repository
@@ -62,4 +61,3 @@ jobs:
BENCHER_API_TOKEN: ${{ secrets.BENCHER_API_TOKEN }}
BENCHER_CMD: cargo bench --all-features
BENCHER_PROJECT: socketioxide
- RUSTFLAGS: --cfg=socketioxide_test
\ No newline at end of file
diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml
index 664c4780..7d295d73 100644
--- a/.github/workflows/github-ci.yml
+++ b/.github/workflows/github-ci.yml
@@ -12,18 +12,16 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@master
- with:
- toolchain: stable
- components: rustfmt
- - run: cargo fmt --all -- --check
- env:
- RUSTFLAGS: --cfg=socketioxide_test
-
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: stable
+ components: rustfmt
+ - run: cargo fmt --all -- --check
+
test:
runs-on: ubuntu-latest
-
+
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
@@ -39,8 +37,6 @@ jobs:
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- run: cargo test --tests --all-features --workspace
- env:
- RUSTFLAGS: --cfg=socketioxide_test
udeps:
runs-on: ubuntu-latest
steps:
@@ -85,13 +81,11 @@ jobs:
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ steps.msrv.outputs.version }}
- uses: dtolnay/rust-toolchain@master
with:
- toolchain: ${{ steps.msrv.outputs.version }}
- components: rustfmt, clippy
+ toolchain: ${{ steps.msrv.outputs.version }}
+ components: rustfmt, clippy
- name: check crates
run: cargo check -p socketioxide -p engineioxide --all-features
- env:
- RUSTFLAGS: --cfg=socketioxide_test
feature_set:
runs-on: ubuntu-latest
@@ -183,20 +177,18 @@ jobs:
run: cargo install clippy-sarif sarif-fmt || true
- name: Run rust-clippy
- run:
- cargo clippy
+ run: cargo clippy
--all-features
+ --tests
--message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
continue-on-error: true
- env:
- RUSTFLAGS: --cfg=socketioxide_test
- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: rust-clippy-results.sarif
wait-for-processing: true
-
+
engine_io:
runs-on: ubuntu-latest
needs: [test]
@@ -226,7 +218,7 @@ jobs:
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-release
- - name: Install deps & run tests
+ - name: Install deps & run tests
run: |
cd engine.io-protocol/test-suite && npm install && cd ../..
cargo build -p engineioxide-e2e --bin engineioxide-e2e --features ${{ matrix.engineio-version }} --release
@@ -236,7 +228,7 @@ jobs:
run: cat server.txt
- name: Client output
if: always()
- run: cat client.txt
+ run: cat client.txt
socket_io:
runs-on: ubuntu-latest
@@ -266,7 +258,7 @@ jobs:
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-release
- - name: Install deps & run tests
+ - name: Install deps & run tests
run: |
cd socket.io-protocol/test-suite && npm install && cd ../..
cargo build -p socketioxide-e2e --bin socketioxide-e2e --features ${{ matrix.socketio-version }} --release
@@ -276,4 +268,4 @@ jobs:
run: cat server.txt
- name: Client output
if: always()
- run: cat client.txt
\ No newline at end of file
+ run: cat client.txt
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4d9068f1..01a23ed8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,7 +16,7 @@ today! As a contributor, here are the guidelines we would like you to follow:
## Got a Question or Problem?
-Please open a discussion on the [Q&A discussions](https://github.com/totodore/socketioxide/discussions) page.
+Please open a discussion on the [Q&A discussions](https://github.com/totodore/socketioxide/discussions) page.
We want to keep GitHub Issues for bugs and feature requests. If you open an issue it will be moved to Discussions.
## Found a Bug?
@@ -139,11 +139,6 @@ You will need [rustc and cargo](www.rust-lang.org/tools/install).
```shell
git clone https://github.com/totodore/socketioxide
```
-2. To test socketioxide don't forget to enable the flag `socketioxide_test` through the `RUSTFLAGS` environment variable:
-
- ```shell
- export RUSTFLAGS="--cfg socketioxide_test"
- ```
2. Depending on what you want to change, clone the [socketio/engine.io-protocol](https://github.com/socketio/engine.io-protocol) repo or the [socketio/socket.io-protocol](https://github.com/socketio/socket.io-protocol) repo or both
```shell
git clone https://github.com/socketio/engine.io-protocol
@@ -261,4 +256,4 @@ The subject contains succinct description of the change:
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
-The body should include the motivation for the change and contrast this with previous behavior.
\ No newline at end of file
+The body should include the motivation for the change and contrast this with previous behavior.
diff --git a/engineioxide/Cargo.toml b/engineioxide/Cargo.toml
index 41ba0341..dde3f270 100644
--- a/engineioxide/Cargo.toml
+++ b/engineioxide/Cargo.toml
@@ -58,6 +58,7 @@ hyper-util = { workspace = true, features = ["tokio", "client-legacy"] }
[features]
v3 = ["memchr", "unicode-segmentation", "itoa"]
tracing = ["dep:tracing"]
+__test_harness = []
[[bench]]
name = "packet_encode"
diff --git a/engineioxide/src/lib.rs b/engineioxide/src/lib.rs
index 14777b7a..142435cf 100644
--- a/engineioxide/src/lib.rs
+++ b/engineioxide/src/lib.rs
@@ -36,7 +36,8 @@ pub use crate::str::Str;
pub use service::{ProtocolVersion, TransportType};
pub use socket::{DisconnectReason, Socket};
-#[cfg(any(test, socketioxide_test))]
+#[doc(hidden)]
+#[cfg(feature = "__test_harness")]
pub use packet::*;
pub mod config;
diff --git a/engineioxide/src/socket.rs b/engineioxide/src/socket.rs
index 700a5571..a1dd24e9 100644
--- a/engineioxide/src/socket.rs
+++ b/engineioxide/src/socket.rs
@@ -126,8 +126,8 @@ pub struct Permit<'a> {
impl Permit<'_> {
/// Consume the permit and emit a message to the client.
#[inline]
- pub fn emit(self, msg: String) {
- self.inner.send(smallvec![Packet::Message(msg.into())]);
+ pub fn emit(self, msg: Str) {
+ self.inner.send(smallvec![Packet::Message(msg)]);
}
/// Consume the permit and emit a binary message to the client.
#[inline]
@@ -138,9 +138,21 @@ impl Permit<'_> {
/// Consume the permit and emit a message with multiple binary data to the client.
///
/// It can be used to ensure atomicity when sending a string packet with adjacent binary packets.
- pub fn emit_many(self, msg: String, data: Vec) {
+ pub fn emit_many(self, msg: Str, data: Vec) {
let mut packets = SmallVec::with_capacity(data.len() + 1);
- packets.push(Packet::Message(msg.into()));
+ packets.push(Packet::Message(msg));
+ for d in data {
+ packets.push(Packet::Binary(d));
+ }
+ self.inner.send(packets);
+ }
+
+ /// Consume the permit and emit a message with multiple binary data to the client.
+ ///
+ /// It can be used to ensure atomicity when sending a string packet with adjacent binary packets.
+ pub fn emit_many_binary(self, bin: Bytes, data: Vec) {
+ let mut packets = SmallVec::with_capacity(data.len() + 1);
+ packets.push(Packet::Binary(bin));
for d in data {
packets.push(Packet::Binary(d));
}
@@ -469,7 +481,8 @@ impl std::fmt::Debug for Socket {
}
}
-#[cfg(socketioxide_test)]
+#[doc(hidden)]
+#[cfg(feature = "__test_harness")]
impl Drop for Socket
where
D: Default + Send + Sync + 'static,
@@ -480,7 +493,8 @@ where
}
}
-#[cfg(any(socketioxide_test, test))]
+#[doc(hidden)]
+#[cfg(feature = "__test_harness")]
impl Socket
where
D: Default + Send + Sync + 'static,
diff --git a/engineioxide/src/str.rs b/engineioxide/src/str.rs
index 0105ce91..c96ecf0c 100644
--- a/engineioxide/src/str.rs
+++ b/engineioxide/src/str.rs
@@ -1,6 +1,6 @@
-use std::borrow::{Borrow, Cow};
-
use bytes::Bytes;
+use serde::{Deserialize, Serialize};
+use std::borrow::{Borrow, Cow};
/// A custom [`Bytes`] wrapper to efficiently store string packets
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd)]
@@ -92,6 +92,43 @@ impl From for String {
unsafe { String::from_utf8_unchecked(vec) }
}
}
+impl Serialize for Str {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: serde::Serializer,
+ {
+ serializer.serialize_str(self.as_str())
+ }
+}
+impl<'de> Deserialize<'de> for Str {
+ fn deserialize(deserializer: D) -> Result
+ where
+ D: serde::Deserializer<'de>,
+ {
+ struct StrVisitor;
+ impl<'de> serde::de::Visitor<'de> for StrVisitor {
+ type Value = Str;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ formatter.write_str("a str")
+ }
+
+ fn visit_str(self, v: &str) -> Result
+ where
+ E: serde::de::Error,
+ {
+ Ok(Str::copy_from_slice(v))
+ }
+ fn visit_string(self, v: String) -> Result
+ where
+ E: serde::de::Error,
+ {
+ Ok(Str::from(v))
+ }
+ }
+ deserializer.deserialize_str(StrVisitor)
+ }
+}
impl std::cmp::PartialEq<&str> for Str {
fn eq(&self, other: &&str) -> bool {
diff --git a/socketioxide/Cargo.toml b/socketioxide/Cargo.toml
index 489addbb..59a5a3e4 100644
--- a/socketioxide/Cargo.toml
+++ b/socketioxide/Cargo.toml
@@ -25,6 +25,7 @@ tower.workspace = true
http.workspace = true
http-body.workspace = true
thiserror.workspace = true
+smallvec.workspace = true
itoa.workspace = true
hyper.workspace = true
matchit.workspace = true
@@ -41,6 +42,7 @@ v4 = ["engineioxide/v3"]
tracing = ["dep:tracing", "engineioxide/tracing"]
extensions = []
state = ["dep:state"]
+__test_harness = ["engineioxide/__test_harness"]
[dev-dependencies]
engineioxide = { path = "../engineioxide", features = ["v3", "tracing"] }
diff --git a/socketioxide/benches/packet_decode.rs b/socketioxide/benches/packet_decode.rs
index 1c902ffc..fad00932 100644
--- a/socketioxide/benches/packet_decode.rs
+++ b/socketioxide/benches/packet_decode.rs
@@ -1,139 +1,175 @@
use bytes::Bytes;
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
use engineioxide::sid::Sid;
+use serde_json::to_value;
use socketioxide::{
packet::{Packet, PacketData},
+ parser::{CommonParser, Parse, TransportPayload},
ProtocolVersion,
};
+
+fn encode(packet: Packet<'_>) -> String {
+ match CommonParser::default().encode(black_box(packet)).0 {
+ TransportPayload::Str(d) => d.into(),
+ TransportPayload::Bytes(_) => panic!("testing only returns str"),
+ }
+}
+fn decode(value: String) -> Option> {
+ CommonParser::default()
+ .decode_str(black_box(value.into()))
+ .ok()
+}
fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("socketio_packet/decode");
group.bench_function("Decode packet connect on /", |b| {
- let packet: String =
- Packet::connect(black_box("/"), black_box(Sid::ZERO), ProtocolVersion::V5).into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
+ b.iter_batched(
+ || encode(Packet::connect("/", Sid::ZERO, ProtocolVersion::V5)),
+ decode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Decode packet connect on /custom_nsp", |b| {
- let packet: String = Packet::connect(
- black_box("/custom_nsp"),
- black_box(Sid::ZERO),
- ProtocolVersion::V5,
+ b.iter_batched(
+ || {
+ encode(Packet::connect(
+ "/custom_nsp",
+ Sid::ZERO,
+ ProtocolVersion::V5,
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
const DATA: &str = r#"{"_placeholder":true,"num":0}"#;
const BINARY: Bytes = Bytes::from_static(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
group.bench_function("Decode packet event on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String =
- Packet::event(black_box("/"), black_box("event"), black_box(data.clone())).into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
+ b.iter_batched(
+ || encode(Packet::event("/", "event", to_value(DATA).unwrap())),
+ decode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Decode packet event on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::event(
- black_box("custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
+ b.iter_batched(
+ || {
+ encode(Packet::event(
+ "custom_nsp",
+ "event",
+ to_value(DATA).unwrap(),
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.bench_function("Decode packet event with ack on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: Packet =
- Packet::event(black_box("/"), black_box("event"), black_box(data.clone()));
- match packet.inner {
- PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
- _ => panic!("Wrong packet type"),
- };
- let packet: String = packet.into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
+ b.iter_batched(
+ || {
+ let packet = Packet::event("/", "event", to_value(DATA).unwrap());
+ match packet.inner {
+ PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
+ _ => panic!("Wrong packet type"),
+ };
+ encode(packet)
+ },
+ decode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Decode packet event with ack on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::event(
- black_box("/custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
- );
- match packet.inner {
- PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
- _ => panic!("Wrong packet type"),
- };
- let packet: String = packet.into();
-
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
+ b.iter_batched(
+ || {
+ let packet = Packet::event("/custom_nsp", "event", to_value(DATA).unwrap());
+ match packet.inner {
+ PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
+ _ => panic!("Wrong packet type"),
+ };
+ encode(packet)
+ },
+ decode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Decode packet ack on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String =
- Packet::ack(black_box("/"), black_box(data.clone()), black_box(0)).into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
+ b.iter_batched(
+ || encode(Packet::ack("/", to_value(DATA).unwrap(), black_box(0))),
+ decode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Decode packet ack on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::ack(
- black_box("/custom_nsp"),
- black_box(data.clone()),
- black_box(0),
+ b.iter_batched(
+ || encode(Packet::ack("/custom_nsp", to_value(DATA).unwrap(), 0)),
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.bench_function("Decode packet binary event (b64) on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::bin_event(
- black_box("/"),
- black_box("event"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
+ b.iter_batched(
+ || {
+ encode(Packet::bin_event(
+ "/",
+ "event",
+ to_value(DATA).unwrap(),
+ vec![BINARY.clone()],
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.bench_function("Decode packet binary event (b64) on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::bin_event(
- black_box("/custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
+ b.iter_batched(
+ || {
+ encode(Packet::bin_event(
+ "/custom_nsp",
+ "event",
+ to_value(DATA).unwrap(),
+ vec![BINARY],
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.bench_function("Decode packet binary ack (b64) on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::bin_ack(
- black_box("/"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- black_box(0),
+ b.iter_batched(
+ || {
+ encode(Packet::bin_ack(
+ "/",
+ to_value(DATA).unwrap(),
+ vec![BINARY.clone()],
+ 0,
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.bench_function("Decode packet binary ack (b64) on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet: String = Packet::bin_ack(
- black_box("/custom_nsp"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- black_box(0),
+ b.iter_batched(
+ || {
+ encode(Packet::bin_ack(
+ "/custom_nsp",
+ to_value(DATA).unwrap(),
+ vec![BINARY.clone()],
+ 0,
+ ))
+ },
+ decode,
+ BatchSize::SmallInput,
)
- .into();
- b.iter(|| Packet::try_from(packet.clone()).unwrap())
});
group.finish();
diff --git a/socketioxide/benches/packet_encode.rs b/socketioxide/benches/packet_encode.rs
index e9c435a9..8952818c 100644
--- a/socketioxide/benches/packet_encode.rs
+++ b/socketioxide/benches/packet_encode.rs
@@ -1,150 +1,146 @@
use bytes::Bytes;
-use criterion::{black_box, criterion_group, criterion_main, Criterion};
+use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
use engineioxide::sid::Sid;
+use serde_json::to_value;
use socketioxide::{
packet::{Packet, PacketData},
+ parser::{CommonParser, Parse, TransportPayload},
ProtocolVersion,
};
+
+fn encode(packet: Packet<'_>) -> String {
+ match CommonParser::default().encode(black_box(packet)).0 {
+ TransportPayload::Str(d) => d.into(),
+ TransportPayload::Bytes(_) => panic!("testing only returns str"),
+ }
+}
+
fn criterion_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("socketio_packet/encode");
+
group.bench_function("Encode packet connect on /", |b| {
- let packet = Packet::connect(black_box("/"), black_box(Sid::ZERO), ProtocolVersion::V5);
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::connect("/", Sid::ZERO, ProtocolVersion::V5),
+ encode,
+ BatchSize::SmallInput,
+ )
});
+
group.bench_function("Encode packet connect on /custom_nsp", |b| {
- let packet = Packet::connect(
- black_box("/custom_nsp"),
- black_box(Sid::ZERO),
- ProtocolVersion::V5,
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::connect("/custom_nsp", Sid::ZERO, ProtocolVersion::V5),
+ encode,
+ BatchSize::SmallInput,
+ )
});
const DATA: &str = r#"{"_placeholder":true,"num":0}"#;
const BINARY: Bytes = Bytes::from_static(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
group.bench_function("Encode packet event on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::event(black_box("/"), black_box("event"), black_box(data.clone()));
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::event("/", "event", to_value(DATA).unwrap()),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet event on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::event(
- black_box("custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::event("custom_nsp", "event", to_value(DATA).unwrap()),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet event with ack on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::event(black_box("/"), black_box("event"), black_box(data.clone()));
- match packet.inner {
- PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
- _ => panic!("Wrong packet type"),
- };
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || {
+ let packet = Packet::event("/", "event", to_value(DATA).unwrap());
+ if let PacketData::Event(_, _, mut ack) = packet.inner {
+ let _ = ack.insert(black_box(0));
+ }
+ packet
+ },
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet event with ack on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::event(
- black_box("/custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
- );
- match packet.inner {
- PacketData::Event(_, _, mut ack) => ack.insert(black_box(0)),
- _ => panic!("Wrong packet type"),
- };
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || {
+ let packet = Packet::event("/custom_nsp", "event", to_value(DATA).unwrap());
+ if let PacketData::Event(_, _, mut ack) = packet.inner {
+ let _ = ack.insert(black_box(0));
+ }
+ packet
+ },
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet ack on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::ack(black_box("/"), black_box(data.clone()), black_box(0));
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::ack("/", to_value(DATA).unwrap(), 0),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet ack on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::ack(
- black_box("/custom_nsp"),
- black_box(data.clone()),
- black_box(0),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::ack("/custom_nsp", to_value(DATA).unwrap(), 0),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet binary event (b64) on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::bin_event(
- black_box("/"),
- black_box("event"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::bin_event("/", "event", to_value(DATA).unwrap(), vec![BINARY.clone()]),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet binary event (b64) on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::bin_event(
- black_box("/custom_nsp"),
- black_box("event"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || {
+ Packet::bin_event(
+ "/custom_nsp",
+ "event",
+ to_value(DATA).unwrap(),
+ vec![BINARY.clone()],
+ )
+ },
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet binary ack (b64) on /", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::bin_ack(
- black_box("/"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- black_box(0),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || Packet::bin_ack("/", to_value(DATA).unwrap(), vec![BINARY.clone()], 0),
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.bench_function("Encode packet binary ack (b64) on /custom_nsp", |b| {
- let data = serde_json::to_value(DATA).unwrap();
- let packet = Packet::bin_ack(
- black_box("/custom_nsp"),
- black_box(data.clone()),
- black_box(vec![BINARY.clone()]),
- black_box(0),
- );
- b.iter(|| {
- let _: String = packet.clone().into();
- })
+ b.iter_batched(
+ || {
+ Packet::bin_ack(
+ "/custom_nsp",
+ to_value(DATA).unwrap(),
+ vec![BINARY.clone()],
+ 0,
+ )
+ },
+ encode,
+ BatchSize::SmallInput,
+ )
});
group.finish();
diff --git a/socketioxide/src/client.rs b/socketioxide/src/client.rs
index 9d8f8ede..355eff1c 100644
--- a/socketioxide/src/client.rs
+++ b/socketioxide/src/client.rs
@@ -10,11 +10,13 @@ use futures_util::{FutureExt, TryFutureExt};
use engineioxide::sid::Sid;
use matchit::{Match, Router};
+use serde_json::Value;
use tokio::sync::oneshot;
use crate::adapter::Adapter;
use crate::handler::ConnectHandler;
use crate::ns::NamespaceCtr;
+use crate::parser::{self, Parse, Parser, TransportPayload};
use crate::socket::DisconnectReason;
use crate::{
errors::Error,
@@ -55,7 +57,7 @@ impl Client {
/// Called when a socket connects to a new namespace
fn sock_connect(
&self,
- auth: Option,
+ auth: Option,
ns_path: Str,
esocket: &Arc>>,
) {
@@ -88,11 +90,22 @@ impl Client {
);
esocket.close(EIoDisconnectReason::TransportClose);
} else {
- let packet: String = Packet::connect_error(ns_path, "Invalid namespace").into();
- if let Err(_e) = esocket.emit(packet) {
- #[cfg(feature = "tracing")]
- tracing::error!("error while sending invalid namespace packet: {}", _e);
- }
+ let (packet, _) = esocket
+ .data
+ .parser
+ .get()
+ .unwrap()
+ .encode(Packet::connect_error(ns_path, "Invalid namespace"));
+ let _ = match packet {
+ TransportPayload::Str(p) => esocket.emit(p).map_err(|_e| {
+ #[cfg(feature = "tracing")]
+ tracing::error!("error while sending invalid namespace packet: {}", _e);
+ }),
+ TransportPayload::Bytes(p) => esocket.emit_binary(p).map_err(|_e| {
+ #[cfg(feature = "tracing")]
+ tracing::error!("error while sending invalid namespace packet: {}", _e);
+ }),
+ };
}
}
@@ -186,9 +199,8 @@ impl Client {
#[derive(Debug)]
pub struct SocketData {
- /// Partial binary packet that is being received
- /// Stored here until all the binary payloads are received
- pub partial_bin_packet: Mutex