Skip to content

Conversation

@krishvishal
Copy link

@krishvishal krishvishal commented Nov 5, 2025

This PR adds compio-ws, a WebSocket library that brings async WebSocket support to the compio runtime. It integrates the tungstenite WebSocket protocol implementation with compio. The structure of this project is mainly based on tokio-tungstenite.

Features

  • Client & Server APIs - Functions for both accepting connections and initiating client connections
  • Full WebSocket Protocol Support - Built on tungstenite for spec-compliant WebSocket handling
  • Optional TLS Support - Secure WebSocket connections via rustls.
  • Added GrowableSyncStream - a SyncStream like structure but with growable internal read/write buffers.
  • Autobahn Test Suite - Scripts and configurations for protocol compliance testing

Feature flags

  • connect - Enables client connection functionality (requires compio-net)
  • rustls - TLS support via rustls
  • rustls-native-certs - Use system native certificates
  • webpki-roots - Use Mozilla's CA roots

Examples

  • echo_server / echo_server_tls - Simple echo servers
  • client / client_tls - Client examples
  • autobahn-client / autobahn-server - Autobahn test suite integration

You can test server and client using the following from the compio root dir:

Run cargo run -p compio-ws --example echo_server --features connect to spin up a WS server and in a separate terminal run cargo run -p compio-ws --example client --features connect

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds WebSocket support to the compio runtime by introducing a new compio-ws crate. It provides async WebSocket functionality built on top of the tungstenite library, with optional TLS support via rustls.

Key Changes:

  • New compio-ws crate with client/server WebSocket support
  • Growable sync stream adapter for bridging async/sync I/O
  • TLS integration with optional certificate loading features
  • Examples demonstrating usage and Autobahn test suite integration

Reviewed Changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
compio-ws/src/lib.rs Core WebSocket stream implementation and handshake functions
compio-ws/src/growable_sync_stream.rs Buffered stream adapter with dynamic growth
compio-ws/src/stream.rs MaybeTlsStream enum for plain/TLS abstraction
compio-ws/src/rustls.rs TLS client support with certificate loading
compio-ws/Cargo.toml Package configuration with feature flags
compio-ws/examples/* Example servers and clients
compio-ws/scripts/* Autobahn test automation scripts
Cargo.toml Workspace configuration update

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Berrysoft
Copy link
Member

You might want to pass the CI first:)

@krishvishal
Copy link
Author

@Berrysoft I've fixed fmt and clippy issues.

I've overlooked that the project uses nightly.

Please run the CI again.

@krishvishal krishvishal changed the title Add compio-ws: Async WebSocket support for compio runtime feat(ws): Add compio-ws: Async WebSocket support for compio runtime Nov 5, 2025
Copy link
Member

@Berrysoft Berrysoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better if there are some tests.

@krishvishal
Copy link
Author

@Berrysoft I've added some tests that test basic websocket functionality and addressed the review comments. Please review when you can.

Copy link
Member

@Berrysoft Berrysoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much! There are some more comments:

  • Would you want to replace the SyncStream in compio-io directly? Well it's OK to keep the current one, and I'll do that if you don't want to spend more time.
  • I hesitated whether to make compio-ws as a separate project, but now it seems that it's not a large codebase, so it's OK. It is necessary to also add compio-ws as the dependency of compio crate, and to add an alias ws, too. The important features of compio-ws should be reflected in the features of compio, so that users won't need to write another individual dependency.
    • Note that although you have added the tests, they didn't run because they need new features. You may add the features to the all feature in compio.
  • @George-Miao is a bit busy now. He commented that tungstenite is a little inefficient because there's a buffer inside, and now we need to add another buffer for the gap between sync code and async code. If you have some other ideas about that, feel free to discuss about it.

@@ -0,0 +1,174 @@
#![cfg(feature = "connect")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding tests! This attribute could be moved to Cargo.toml as [[test]] sections.


[dependencies]
rustls = { workspace = true, optional = true, default-features = false }
rustls-native-certs = { version = "0.8", optional = true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to notice that rustls-platform-verifier is more usable than rustls-native-certs. We use the former in compio-quic.

repository = "https://github.com/compio-rs/compio"

[workspace.dependencies]
compio = { path = "./compio", version = "0.16.0" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this line is removable now.

/// Stream that can be either plain TCP or TLS-encrypted
#[derive(Debug)]
#[allow(clippy::large_enum_variant)]
pub enum MaybeTlsStream<S> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment: If you want it to be public, it's better to put it inside compio-tls.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this one is actually OK. If you don't move it, I think I'll do that in the future (or just make it private?).

}
}

impl<S> Unpin for MaybeTlsStream<S> where S: Unpin {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be automatic. Did you meet some problems?

let (tx, rx) = oneshot::channel();

compio_runtime::spawn(async move {
let listener = TcpListener::bind("127.0.0.1:12345").await.unwrap();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Port 12345 can be used during tests so you can false-fail here.
Let's let OS choose port for us:

let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
let conn = TcpStream::connect(&addr).await.unwrap();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants