diff --git a/Cargo.toml b/Cargo.toml index 54f4078294d..b10e03d1124 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,9 +78,6 @@ rsa = ["libp2p-core/rsa"] ecdsa = ["libp2p-core/ecdsa"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] -[package.metadata.docs.rs] -all-features = true - [dependencies] bytes = "1" futures = "0.3.1" @@ -201,3 +198,8 @@ required-features = ["full"] [[example]] name = "distributed-key-value-store" required-features = ["full"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] \ No newline at end of file diff --git a/core/Cargo.toml b/core/Cargo.toml index c0881afe619..d58ca63ca1f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -64,3 +64,8 @@ serde = ["multihash/serde-codec", "dep:serde"] [[bench]] name = "peer_id" harness = false + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/core/src/identity.rs b/core/src/identity.rs index af5dceb69ee..1607fe00bef 100644 --- a/core/src/identity.rs +++ b/core/src/identity.rs @@ -33,11 +33,14 @@ //! All key types have functions to enable conversion to/from their binary representations. #[cfg(feature = "ecdsa")] +#[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))] pub mod ecdsa; pub mod ed25519; #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "rsa", not(target_arch = "wasm32")))))] pub mod rsa; #[cfg(feature = "secp256k1")] +#[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))] pub mod secp256k1; pub mod error; @@ -70,12 +73,15 @@ pub enum Keypair { Ed25519(ed25519::Keypair), /// An RSA keypair. #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rsa", not(target_arch = "wasm32")))))] Rsa(rsa::Keypair), /// A Secp256k1 keypair. #[cfg(feature = "secp256k1")] + #[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))] Secp256k1(secp256k1::Keypair), /// An ECDSA keypair. #[cfg(feature = "ecdsa")] + #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))] Ecdsa(ecdsa::Keypair), } @@ -87,12 +93,14 @@ impl Keypair { /// Generate a new Secp256k1 keypair. #[cfg(feature = "secp256k1")] + #[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))] pub fn generate_secp256k1() -> Keypair { Keypair::Secp256k1(secp256k1::Keypair::generate()) } /// Generate a new ECDSA keypair. #[cfg(feature = "ecdsa")] + #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))] pub fn generate_ecdsa() -> Keypair { Keypair::Ecdsa(ecdsa::Keypair::generate()) } @@ -102,6 +110,7 @@ impl Keypair { /// /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rsa", not(target_arch = "wasm32")))))] pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result { rsa::Keypair::from_pkcs8(pkcs8_der).map(Keypair::Rsa) } @@ -111,6 +120,7 @@ impl Keypair { /// /// [RFC5915]: https://tools.ietf.org/html/rfc5915 #[cfg(feature = "secp256k1")] + #[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))] pub fn secp256k1_from_der(der: &mut [u8]) -> Result { secp256k1::SecretKey::from_der(der) .map(|sk| Keypair::Secp256k1(secp256k1::Keypair::from(sk))) @@ -218,14 +228,17 @@ impl zeroize::Zeroize for keys_proto::PrivateKey { pub enum PublicKey { /// A public Ed25519 key. Ed25519(ed25519::PublicKey), - #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] /// A public RSA key. + #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "rsa", not(target_arch = "wasm32")))))] Rsa(rsa::PublicKey), - #[cfg(feature = "secp256k1")] /// A public Secp256k1 key. + #[cfg(feature = "secp256k1")] + #[cfg_attr(docsrs, doc(cfg(feature = "secp256k1")))] Secp256k1(secp256k1::PublicKey), /// A public ECDSA key. #[cfg(feature = "ecdsa")] + #[cfg_attr(docsrs, doc(cfg(feature = "ecdsa")))] Ecdsa(ecdsa::PublicKey), } diff --git a/core/src/lib.rs b/core/src/lib.rs index ac55537eb0b..5935b4f4ca8 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -35,6 +35,8 @@ //! define how to upgrade each individual substream to use a protocol. //! See the `upgrade` module. +#![cfg_attr(docsrs, feature(doc_cfg))] + #[allow(clippy::derive_partial_eq_without_eq)] mod keys_proto { include!(concat!(env!("OUT_DIR"), "/keys_proto.rs")); diff --git a/core/src/peer_id.rs b/core/src/peer_id.rs index 9e7a1f238cf..aed3c9b5534 100644 --- a/core/src/peer_id.rs +++ b/core/src/peer_id.rs @@ -180,6 +180,7 @@ impl From for Vec { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl Serialize for PeerId { fn serialize(&self, serializer: S) -> Result where @@ -194,6 +195,7 @@ impl Serialize for PeerId { } #[cfg(feature = "serde")] +#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de> Deserialize<'de> for PeerId { fn deserialize(deserializer: D) -> Result where diff --git a/misc/metrics/Cargo.toml b/misc/metrics/Cargo.toml index 643d96e67ab..4c48b3ab209 100644 --- a/misc/metrics/Cargo.toml +++ b/misc/metrics/Cargo.toml @@ -38,3 +38,8 @@ futures = "0.3.1" libp2p = { path = "../..", features = ["full"] } hyper = { version="0.14", features = ["server", "tcp", "http1"] } tokio = { version = "1", features = ["rt-multi-thread"] } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/misc/metrics/src/lib.rs b/misc/metrics/src/lib.rs index bc9f45b8d76..38ac4230076 100644 --- a/misc/metrics/src/lib.rs +++ b/misc/metrics/src/lib.rs @@ -25,6 +25,8 @@ //! //! See `examples` directory for more. +#![cfg_attr(docsrs, feature(doc_cfg))] + #[cfg(feature = "dcutr")] mod dcutr; #[cfg(feature = "gossipsub")] @@ -97,14 +99,18 @@ pub trait Recorder { } #[cfg(feature = "dcutr")] +#[cfg_attr(docsrs, doc(cfg(feature = "dcutr")))] impl Recorder for Metrics { fn record(&self, event: &libp2p_dcutr::behaviour::Event) { self.dcutr.record(event) } } -#[cfg(feature = "gossipsub")] -#[cfg(not(target_os = "unknown"))] +#[cfg(all(feature = "gossipsub", not(target_os = "unknown")))] +#[cfg_attr( + docsrs, + doc(cfg(all(feature = "gossipsub", not(target_os = "unknown")))) +)] impl Recorder for Metrics { fn record(&self, event: &libp2p_gossipsub::GossipsubEvent) { self.gossipsub.record(event) @@ -112,6 +118,7 @@ impl Recorder for Metrics { } #[cfg(feature = "identify")] +#[cfg_attr(docsrs, doc(cfg(feature = "identify")))] impl Recorder for Metrics { fn record(&self, event: &libp2p_identify::Event) { self.identify.record(event) @@ -119,20 +126,23 @@ impl Recorder for Metrics { } #[cfg(feature = "kad")] +#[cfg_attr(docsrs, doc(cfg(feature = "kad")))] impl Recorder for Metrics { fn record(&self, event: &libp2p_kad::KademliaEvent) { self.kad.record(event) } } -#[cfg(feature = "ping")] +#[cfg(any(feature = "ping", docsrs))] +#[cfg_attr(docsrs, doc(cfg(feature = "ping")))] impl Recorder for Metrics { fn record(&self, event: &libp2p_ping::Event) { self.ping.record(event) } } -#[cfg(feature = "relay")] +#[cfg(any(feature = "relay", docsrs))] +#[cfg_attr(docsrs, doc(cfg(feature = "relay")))] impl Recorder for Metrics { fn record(&self, event: &libp2p_relay::v2::relay::Event) { self.relay.record(event) diff --git a/muxers/yamux/Cargo.toml b/muxers/yamux/Cargo.toml index 10800a78c3c..786b2b93b92 100644 --- a/muxers/yamux/Cargo.toml +++ b/muxers/yamux/Cargo.toml @@ -17,3 +17,4 @@ parking_lot = "0.12" thiserror = "1.0" yamux = "0.10.0" log = "0.4" + diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 00778ef0688..f102f3b7a36 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -43,3 +43,6 @@ derive_builder = "0.11.1" [build-dependencies] prost-build = "0.11" + +[package.metadata.docs.rs] +all-features = true diff --git a/protocols/kad/Cargo.toml b/protocols/kad/Cargo.toml index e97394b7071..e254cc602cd 100644 --- a/protocols/kad/Cargo.toml +++ b/protocols/kad/Cargo.toml @@ -43,3 +43,6 @@ prost-build = "0.11" [features] serde = ["dep:serde", "bytes/serde"] + +[package.metadata.docs.rs] +all-features = true diff --git a/protocols/mdns/Cargo.toml b/protocols/mdns/Cargo.toml index 466c9eb9e25..4298c2e5636 100644 --- a/protocols/mdns/Cargo.toml +++ b/protocols/mdns/Cargo.toml @@ -46,3 +46,7 @@ required-features = ["async-io"] name = "use-tokio" required-features = ["tokio"] +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index d645468ed5c..7595acf645c 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -39,17 +39,21 @@ use std::collections::hash_map::{Entry, HashMap}; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] use crate::behaviour::{socket::asio::AsyncUdpSocket, timer::asio::AsyncTimer}; /// The type of a [`GenMdns`] using the `async-io` implementation. #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub type Mdns = GenMdns; #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] use crate::behaviour::{socket::tokio::TokioUdpSocket, timer::tokio::TokioTimer}; /// The type of a [`GenMdns`] using the `tokio` implementation. #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub type TokioMdns = GenMdns; /// A `NetworkBehaviour` for mDNS. Automatically discovers peers on the local network and adds diff --git a/protocols/mdns/src/behaviour/socket.rs b/protocols/mdns/src/behaviour/socket.rs index 4406ed33fde..52affc661c1 100644 --- a/protocols/mdns/src/behaviour/socket.rs +++ b/protocols/mdns/src/behaviour/socket.rs @@ -49,6 +49,7 @@ pub trait AsyncSocket: Unpin + Send + 'static { } #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub mod asio { use super::*; use async_io::Async; @@ -92,6 +93,7 @@ pub mod asio { } #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub mod tokio { use super::*; use ::tokio::{io::ReadBuf, net::UdpSocket as TkUdpSocket}; diff --git a/protocols/mdns/src/behaviour/timer.rs b/protocols/mdns/src/behaviour/timer.rs index fbdeb065b70..47fb6b3a41b 100644 --- a/protocols/mdns/src/behaviour/timer.rs +++ b/protocols/mdns/src/behaviour/timer.rs @@ -44,6 +44,7 @@ pub trait Builder: Send + Unpin + 'static { } #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub mod asio { use super::*; use async_io::Timer as AsioTimer; @@ -82,6 +83,7 @@ pub mod asio { } #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub mod tokio { use super::*; use ::tokio::time::{self, Instant as TokioInstant, Interval, MissedTickBehavior}; diff --git a/protocols/mdns/src/lib.rs b/protocols/mdns/src/lib.rs index 3b484c91daa..11b9fe35437 100644 --- a/protocols/mdns/src/lib.rs +++ b/protocols/mdns/src/lib.rs @@ -30,6 +30,9 @@ //! implements the `NetworkBehaviour` trait. This struct will automatically discover other //! libp2p nodes on the local network. //! + +#![cfg_attr(docsrs, feature(doc_cfg))] + use lazy_static::lazy_static; use std::net::{Ipv4Addr, Ipv6Addr}; use std::time::Duration; @@ -38,9 +41,11 @@ mod behaviour; pub use crate::behaviour::{GenMdns, MdnsEvent}; #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub use crate::behaviour::Mdns; #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub use crate::behaviour::TokioMdns; /// The DNS service name for all libp2p peers used to query for addresses. diff --git a/src/lib.rs b/src/lib.rs index 96a197cf516..aadbb75b46a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,7 @@ #![doc(html_logo_url = "https://libp2p.io/img/logo_small.png")] #![doc(html_favicon_url = "https://libp2p.io/img/favicon.png")] +#![cfg_attr(docsrs, feature(doc_cfg))] pub use bytes; pub use futures; diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index baab666b0eb..7d16ab0eacd 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -23,3 +23,7 @@ libp2p = { path = "..", features = ["full"] } either = "1.6.0" futures = "0.3.1" void = "1" +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index adbb81cd70e..5a260ffea70 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -29,3 +29,8 @@ async-std = { version = "1.6.2", features = ["attributes"] } env_logger = "0.9" libp2p = { path = "..", features = ["full"] } quickcheck = { package = "quickcheck-ext", path = "../misc/quickcheck-ext" } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] \ No newline at end of file diff --git a/transports/dns/Cargo.toml b/transports/dns/Cargo.toml index 35dce0404b6..41126ef53b7 100644 --- a/transports/dns/Cargo.toml +++ b/transports/dns/Cargo.toml @@ -32,3 +32,8 @@ tokio = ["trust-dns-resolver/tokio-runtime"] # available for `tokio`. tokio-dns-over-rustls = ["tokio", "trust-dns-resolver/dns-over-rustls"] tokio-dns-over-https-rustls = ["tokio", "trust-dns-resolver/dns-over-https-rustls"] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/transports/dns/src/lib.rs b/transports/dns/src/lib.rs index 7f76a378990..4a6a7f4f23f 100644 --- a/transports/dns/src/lib.rs +++ b/transports/dns/src/lib.rs @@ -54,6 +54,8 @@ //! //![trust-dns-resolver]: https://docs.rs/trust-dns-resolver/latest/trust_dns_resolver/#dns-over-tls-and-dns-over-https +#![cfg_attr(docsrs, feature(doc_cfg))] + #[cfg(feature = "async-std")] use async_std_resolver::{AsyncStdConnection, AsyncStdConnectionProvider}; use futures::{future::BoxFuture, prelude::*}; @@ -107,11 +109,13 @@ const MAX_TXT_RECORDS: usize = 16; /// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses /// using `async-std` for all async I/O. #[cfg(feature = "async-std")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))] pub type DnsConfig = GenDnsConfig; /// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses /// using `tokio` for all async I/O. #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub type TokioDnsConfig = GenDnsConfig; /// A `Transport` wrapper for performing DNS lookups when dialing `Multiaddr`esses. @@ -127,6 +131,7 @@ where } #[cfg(feature = "async-std")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))] impl DnsConfig { /// Creates a new [`DnsConfig`] from the OS's DNS configuration and defaults. pub async fn system(inner: T) -> Result, io::Error> { @@ -148,6 +153,7 @@ impl DnsConfig { } #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] impl TokioDnsConfig { /// Creates a new [`TokioDnsConfig`] from the OS's DNS configuration and defaults. pub fn system(inner: T) -> Result, io::Error> { diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index 06517a84f67..dd245590f05 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -29,3 +29,8 @@ async-io = ["async-io-crate"] async-std = { version = "1.6.5", features = ["attributes"] } tokio-crate = { package = "tokio", version = "1.0.1", default-features = false, features = ["net", "rt", "macros"] } env_logger = "0.9.0" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/transports/tcp/src/lib.rs b/transports/tcp/src/lib.rs index f7b897c0d47..132abf10890 100644 --- a/transports/tcp/src/lib.rs +++ b/transports/tcp/src/lib.rs @@ -26,21 +26,27 @@ //! the enabled features, which implement the `Transport` trait for use as a //! transport with `libp2p-core` or `libp2p-swarm`. +#![cfg_attr(docsrs, feature(doc_cfg))] + mod provider; use if_watch::{IfEvent, IfWatcher}; #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub use provider::async_io; /// The type of a [`GenTcpTransport`] using the `async-io` implementation. #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub type TcpTransport = GenTcpTransport; #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub use provider::tokio; /// The type of a [`GenTcpTransport`] using the `tokio` implementation. #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub type TokioTcpTransport = GenTcpTransport; use futures::{ diff --git a/transports/tcp/src/provider.rs b/transports/tcp/src/provider.rs index a341026e7e6..9251f557ace 100644 --- a/transports/tcp/src/provider.rs +++ b/transports/tcp/src/provider.rs @@ -21,9 +21,11 @@ //! The interface for providers of non-blocking TCP implementations. #[cfg(feature = "async-io")] +#[cfg_attr(docsrs, doc(cfg(feature = "async-io")))] pub mod async_io; #[cfg(feature = "tokio")] +#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))] pub mod tokio; use futures::future::BoxFuture; diff --git a/transports/uds/Cargo.toml b/transports/uds/Cargo.toml index e9483f503d1..1143df81bf7 100644 --- a/transports/uds/Cargo.toml +++ b/transports/uds/Cargo.toml @@ -19,3 +19,8 @@ tokio = { version = "1.15", default-features = false, features = ["net"], option [target.'cfg(all(unix, not(target_os = "emscripten")))'.dev-dependencies] tempfile = "3.0" + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] \ No newline at end of file diff --git a/transports/uds/src/lib.rs b/transports/uds/src/lib.rs index 71e6c094013..2c027148c32 100644 --- a/transports/uds/src/lib.rs +++ b/transports/uds/src/lib.rs @@ -31,6 +31,7 @@ //! The `UdsConfig` structs implements the `Transport` trait of the `core` library. See the //! documentation of `core` and of libp2p in general to learn how to use the `Transport` trait. +#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg(all( unix, not(target_os = "emscripten"), diff --git a/transports/wasm-ext/Cargo.toml b/transports/wasm-ext/Cargo.toml index b4f290e7676..a1138e47af0 100644 --- a/transports/wasm-ext/Cargo.toml +++ b/transports/wasm-ext/Cargo.toml @@ -20,3 +20,8 @@ wasm-bindgen-futures = "0.4.4" [features] websocket = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/transports/wasm-ext/src/lib.rs b/transports/wasm-ext/src/lib.rs index bb1e3ea0653..b34333e21dc 100644 --- a/transports/wasm-ext/src/lib.rs +++ b/transports/wasm-ext/src/lib.rs @@ -32,6 +32,8 @@ //! module. //! +#![cfg_attr(docsrs, feature(doc_cfg))] + use futures::{future::Ready, prelude::*, ready, stream::SelectAll}; use libp2p_core::{ connection::Endpoint, @@ -137,6 +139,7 @@ pub mod ffi { } #[cfg(feature = "websocket")] + #[cfg_attr(docsrs, doc(cfg(feature = "websocket")))] #[wasm_bindgen(module = "/src/websockets.js")] extern "C" { /// Returns a `Transport` implemented using websockets.