From ff9fbd49eca18780f0962ad3cfa26ae1575b52fc Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Thu, 6 Jun 2024 19:25:54 +0100 Subject: [PATCH] Starting a move towards ezsockets --- Cargo.lock | 552 ++++++++++++++------------------- side-node/Cargo.toml | 9 +- side-node/src/main.rs | 45 ++- side-node/src/websocket/mod.rs | 46 +-- side-watcher/Cargo.toml | 6 +- side-watcher/src/main.rs | 217 +++++++++++-- 6 files changed, 494 insertions(+), 381 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98d8bee..07be862 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,15 +29,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -219,6 +210,17 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-trait" version = "0.1.80" @@ -230,6 +232,17 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "atomic_enum" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6227a8d6fdb862bcb100c4314d0d9579e5cd73fa6df31a2e6f6e1acd3c5f1207" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "auto_ops" version = "0.3.0" @@ -263,12 +276,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.13.1" @@ -500,6 +507,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -521,16 +537,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -546,6 +552,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -781,6 +793,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "enfync" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce8c1fbec15a38aced3838c4d7ea90a1403bd50364b5cfe8008e679df0c8dde" +dependencies = [ + "async-trait", + "futures", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasmtimer", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -788,14 +814,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "errno" -version = "0.3.9" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "eyre" @@ -807,6 +829,32 @@ dependencies = [ "once_cell", ] +[[package]] +name = "ezsockets" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897108017392f356bd207aa417dfeee5e91d1184b81856ddd6850cfc01aa6839" +dependencies = [ + "async-channel", + "async-trait", + "atomic_enum", + "base64 0.21.7", + "cfg-if", + "enfync", + "futures", + "futures-util", + "getrandom 0.2.15", + "http", + "tokio", + "tokio-tungstenite", + "tokio-tungstenite-wasm", + "tracing", + "tungstenite", + "url", + "wasm-bindgen-futures", + "wasmtimer", +] + [[package]] name = "fastcrypto" version = "0.1.8" @@ -871,12 +919,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - [[package]] name = "ff" version = "0.13.0" @@ -887,40 +929,12 @@ dependencies = [ "subtle", ] -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin 0.9.8", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1270,7 +1284,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -1295,12 +1309,6 @@ dependencies = [ "libc", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "lock_api" version = "0.4.12" @@ -1344,29 +1352,13 @@ dependencies = [ ] [[package]] -name = "nanorand" -version = "0.7.0" +name = "nu-ansi-term" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "overload", + "winapi", ] [[package]] @@ -1463,56 +1455,18 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "p256" version = "0.13.2" @@ -1578,26 +1532,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1642,12 +1576,6 @@ dependencies = [ "spki 0.7.3", ] -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - [[package]] name = "powerfmt" version = "0.2.0" @@ -1818,35 +1746,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - [[package]] name = "rfc6979" version = "0.4.0" @@ -1893,34 +1792,12 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "schemars" version = "0.8.21" @@ -1985,29 +1862,6 @@ dependencies = [ "cc", ] -[[package]] -name = "security-framework" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.23" @@ -2123,19 +1977,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha1" version = "0.10.6" @@ -2194,15 +2035,26 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "side-node" version = "0.1.0" dependencies = [ + "async-trait", "base64 0.21.7", "bft-crdt-derive", "bft-json-crdt", "clap", "dirs", + "ezsockets", "fastcrypto", "serde", "serde_json", @@ -2210,14 +2062,20 @@ dependencies = [ "sha256", "tokio", "toml", - "websockets", + "tracing", + "tracing-subscriber", + "url", ] [[package]] name = "side-watcher" version = "0.1.0" dependencies = [ - "simple-websockets", + "async-trait", + "ezsockets", + "tokio", + "tracing", + "tracing-subscriber", ] [[package]] @@ -2239,18 +2097,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simple-websockets" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f38cc14717bb624d10e9bb4fff30344e8f540c0d2c0f876f8fb0111d808ee7c" -dependencies = [ - "flume", - "futures-util", - "tokio", - "tokio-tungstenite", -] - [[package]] name = "slab" version = "0.4.9" @@ -2282,15 +2128,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spki" version = "0.6.0" @@ -2357,18 +2194,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "thiserror" version = "1.0.61" @@ -2389,6 +2214,16 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -2485,21 +2320,11 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-tungstenite" -version = "0.19.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", @@ -2507,6 +2332,24 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "tokio-tungstenite-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ec8c7cf09b20184f946f114e3d8c0deca34368912c90100812861c14bb63b66" +dependencies = [ + "futures-channel", + "futures-util", + "http", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "toml" version = "0.8.14" @@ -2553,10 +2396,67 @@ dependencies = [ ] [[package]] -name = "tungstenite" -version = "0.19.0" +name = "tracing" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", @@ -2628,10 +2528,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "vcpkg" -version = "0.2.15" +name = "valuable" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "version_check" @@ -2682,6 +2582,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.92" @@ -2712,23 +2624,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] -name = "websockets" -version = "0.3.0" +name = "wasmtimer" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67db5ecf42b65ca21f25689299cc05e216739bbc4fdeeaf598322a1aec34a8d7" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" dependencies = [ - "base64 0.12.3", - "flume", "futures", - "native-tls", - "rand 0.7.3", - "rand_chacha 0.2.2", - "regex", - "sha-1", - "thiserror", - "tokio", - "tokio-native-tls", - "url", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", ] [[package]] diff --git a/side-node/Cargo.toml b/side-node/Cargo.toml index 7ec7a46..129e015 100644 --- a/side-node/Cargo.toml +++ b/side-node/Cargo.toml @@ -6,20 +6,25 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.52" base64 = "0.21.7" bft-json-crdt = { path = "../crates/bft-json-crdt" } bft-crdt-derive = { path = "../crates/bft-json-crdt/bft-crdt-derive" } clap = { version = "4.5.4", features = ["derive"] } dirs = "5.0.1" +ezsockets = { version = "*", features = ["client"] } +fastcrypto = "0.1.8" # serde_cbor = "0.11.2" # move to this once we need to pack things in CBOR serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.117" serde_with = "3.8.1" sha256 = "1.5.0" tokio = { version = "1.37.0", features = ["full"] } -websockets = "0.3.0" +tracing = "0.1.32" +tracing-subscriber = "0.3.9" toml = "0.8.14" -fastcrypto = "0.1.8" +url = "2.2.2" + [features] default = ["bft", "logging-list", "logging-json"] diff --git a/side-node/src/main.rs b/side-node/src/main.rs index a7c3f65..d65cd7d 100644 --- a/side-node/src/main.rs +++ b/side-node/src/main.rs @@ -1,4 +1,4 @@ -use cli::{parse_args, Commands}; +/** use cli::{parse_args, Commands}; pub(crate) mod cli; pub(crate) mod init; @@ -34,3 +34,46 @@ fn home(name: &String) -> std::path::PathBuf { path.push(name); path } +**/ +use async_trait::async_trait; +use ezsockets::ClientConfig; +use std::io::BufRead; + +struct Client {} + +#[async_trait] +impl ezsockets::ClientExt for Client { + type Call = (); + + async fn on_text(&mut self, text: String) -> Result<(), ezsockets::Error> { + tracing::info!("received message: {text}"); + Ok(()) + } + + async fn on_binary(&mut self, bytes: Vec) -> Result<(), ezsockets::Error> { + tracing::info!("received bytes: {bytes:?}"); + Ok(()) + } + + async fn on_call(&mut self, call: Self::Call) -> Result<(), ezsockets::Error> { + let () = call; + Ok(()) + } +} + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + let config = ClientConfig::new("ws://localhost:8080/websocket"); + let (handle, future) = ezsockets::connect(|_client| Client {}, config).await; + tokio::spawn(async move { + future.await.unwrap(); + }); + let stdin = std::io::stdin(); + let lines = stdin.lock().lines(); + for line in lines { + let line = line.unwrap(); + tracing::info!("sending {line}"); + handle.text(line).unwrap(); + } +} diff --git a/side-node/src/websocket/mod.rs b/side-node/src/websocket/mod.rs index 7e9553d..f795924 100644 --- a/side-node/src/websocket/mod.rs +++ b/side-node/src/websocket/mod.rs @@ -1,41 +1,23 @@ -use crate::list_transaction_crdt::{self, CrdtList}; -use base64::{engine::general_purpose, Engine as _}; -use bft_json_crdt::json_crdt::BaseCrdt; -use bft_json_crdt::json_crdt::SignedOp; -use bft_json_crdt::keypair::Ed25519KeyPair; -use tokio::time; -use websockets::WebSocket; -/// Starts a websocket and periodically sends a BFT-CRDT message to the websocket server -pub(crate) async fn start( - keys: Ed25519KeyPair, - bft_crdt: &mut BaseCrdt, -) -> Result<(), websockets::WebSocketError> { - println!("connecting to websocket at ws://127.0.0.1:8080/"); - let mut ws = WebSocket::connect("ws://127.0.0.1:8080/").await?; +/* - let mut interval = every_ten_seconds(); - let mut count = 0; - loop { - let _ = list_transaction_crdt::send(count, bft_crdt, &mut ws, &keys).await; +loop { + let _ = list_transaction_crdt::send(count, bft_crdt, &mut ws, &keys).await; - let msg = ws.receive().await?; + let msg = ws.receive().await?; - // deserialize the received websocket Frame into a string - let msg = msg.into_text().unwrap().0; + // deserialize the received websocket Frame into a string + let msg = msg.into_text().unwrap().0; - // deserialize the message into a Transaction struct - let incoming_operation: SignedOp = serde_json::from_str(&msg).unwrap(); + // deserialize the message into a Transaction struct + let incoming_operation: SignedOp = serde_json::from_str(&msg).unwrap(); - let author = general_purpose::STANDARD.encode(&incoming_operation.author()); - println!("Received from {:?}", author); + let author = general_purpose::STANDARD.encode(&incoming_operation.author()); + println!("Received from {:?}", author); - bft_crdt.apply(incoming_operation.clone()); + bft_crdt.apply(incoming_operation.clone()); - count = count + 1; - interval.tick().await; - } + count = count + 1; + interval.tick().await; } -fn every_ten_seconds() -> time::Interval { - time::interval(time::Duration::from_secs(10)) -} +*/ diff --git a/side-watcher/Cargo.toml b/side-watcher/Cargo.toml index b5d2de3..c4ce9d8 100644 --- a/side-watcher/Cargo.toml +++ b/side-watcher/Cargo.toml @@ -6,4 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -simple-websockets = "0.1.6" +async-trait = "0.1.52" +ezsockets = { version = "*", features = ["tungstenite"] } +tokio = { version = "1.17.0", features = ["full"] } +tracing = "0.1.32" +tracing-subscriber = "0.3.9" diff --git a/side-watcher/src/main.rs b/side-watcher/src/main.rs index 773f980..5973b1a 100644 --- a/side-watcher/src/main.rs +++ b/side-watcher/src/main.rs @@ -1,34 +1,197 @@ -use simple_websockets::{Event, Responder}; +use async_trait::async_trait; +use ezsockets::CloseFrame; +use ezsockets::Error; +use ezsockets::Server; use std::collections::HashMap; +use std::net::SocketAddr; -fn main() { - let event_hub = simple_websockets::launch(8080).expect("failed to listen on port 8080"); - let mut clients: HashMap = HashMap::new(); - println!("Listening for websocket connection..."); - loop { - match event_hub.poll_event() { - Event::Connect(client_id, responder) => { - println!("A client connected with id #{}", client_id); - // add their Responder to our `clients` map: - clients.insert(client_id, responder); - } - Event::Disconnect(client_id) => { - println!("Client #{} disconnected.", client_id); - // remove the disconnected client from the clients map: - clients.remove(&client_id); - } - Event::Message(client_id, message) => { - println!("\nReceived a message from client #{}", client_id); +const DEFAULT_ROOM: &str = "main"; - let all_clients = clients.keys().collect::>(); - for client in all_clients { - if *client != client_id { - println!("Sending message to client #{}", client); - let responder = clients.get(client).unwrap(); - responder.send(message.clone()); - } +type SessionID = u8; +type Session = ezsockets::Session; + +#[derive(Debug)] +enum Message { + Join { + id: SessionID, + room: String, + }, + Send { + from: SessionID, + room: String, + text: String, + }, +} + +struct ChatServer { + sessions: HashMap, + rooms: HashMap>, + handle: Server, +} + +#[async_trait] +impl ezsockets::ServerExt for ChatServer { + type Call = Message; + type Session = SessionActor; + + async fn on_connect( + &mut self, + socket: ezsockets::Socket, + _request: ezsockets::Request, + _address: SocketAddr, + ) -> Result> { + let id = (0..).find(|i| !self.sessions.contains_key(i)).unwrap_or(0); + let session = Session::create( + |session_handle| SessionActor { + id, + server: self.handle.clone(), + session: session_handle, + room: DEFAULT_ROOM.to_string(), + }, + id, + socket, + ); + self.sessions.insert(id, session.clone()); + self.rooms.get_mut(DEFAULT_ROOM).unwrap().push(id); + Ok(session) + } + + async fn on_disconnect( + &mut self, + id: ::ID, + _reason: Result, Error>, + ) -> Result<(), Error> { + assert!(self.sessions.remove(&id).is_some()); + + let (ids, n) = self + .rooms + .values_mut() + .find_map(|ids| ids.iter().position(|v| id == *v).map(|n| (ids, n))) + .expect("could not find session in any room"); + ids.remove(n); + Ok(()) + } + + async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> { + match call { + Message::Send { from, room, text } => { + let (ids, sessions): (Vec, Vec<&Session>) = self + .rooms + .get(&room) + .unwrap() + .iter() + .filter(|id| **id != from) + .map(|id| (id, self.sessions.get(id).unwrap())) + .unzip(); + + tracing::info!( + "sending {text} to [{sessions}] at `{room}`", + sessions = ids + .iter() + .map(|id| id.to_string()) + .collect::>() + .join(",") + ); + for session in sessions { + session.text(text.clone()).unwrap(); } } - } + Message::Join { id, room } => { + let (ids, n) = self + .rooms + .values_mut() + .find_map(|ids| ids.iter().position(|v| id == *v).map(|n| (ids, n))) + .expect("could not find session in any room"); + ids.remove(n); + if let Some(ids) = self.rooms.get_mut(&room) { + ids.push(id); + } else { + self.rooms.insert(room.clone(), vec![id]); + } + + let sessions = self + .rooms + .get(&room) + .unwrap() + .iter() + .map(|id| self.sessions.get(id).unwrap()); + + for session in sessions { + session + .text(format!("User with ID: {id} just joined {room} room")) + .unwrap(); + } + } + }; + Ok(()) } } + +struct SessionActor { + id: SessionID, + server: Server, + session: Session, + room: String, +} + +#[async_trait] +impl ezsockets::SessionExt for SessionActor { + type ID = SessionID; + type Call = (); + + fn id(&self) -> &Self::ID { + &self.id + } + + async fn on_text(&mut self, text: String) -> Result<(), Error> { + tracing::info!("received: {text}"); + if text.starts_with('/') { + let mut args = text.split_whitespace(); + let command = args.next().unwrap(); + if command == "/join" { + let room = args.next().expect("missing argument").to_string(); + tracing::info!("moving {} to {room}", self.id); + self.room = room.clone(); + self.server + .call(Message::Join { id: self.id, room }) + .unwrap(); + } else { + tracing::error!("unrecognized command: {text}"); + } + } else { + self.server + .call(Message::Send { + text, + from: self.id, + room: self.room.clone(), + }) + .unwrap(); + } + Ok(()) + } + + async fn on_binary(&mut self, bytes: Vec) -> Result<(), Error> { + // echo bytes back (we use this for a hacky ping/pong protocol for the wasm client demo) + tracing::info!("echoing bytes: {bytes:?}"); + self.session.binary("pong".as_bytes())?; + Ok(()) + } + + async fn on_call(&mut self, call: Self::Call) -> Result<(), Error> { + let () = call; + Ok(()) + } +} + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + let (server, _) = Server::create(|handle| ChatServer { + sessions: HashMap::new(), + rooms: HashMap::from_iter([(DEFAULT_ROOM.to_string(), vec![])]), + handle, + }); + ezsockets::tungstenite::run(server, "127.0.0.1:8080") + .await + .unwrap(); +}