From be6ea1105229b72a727a699ea2be0b9ca99569aa Mon Sep 17 00:00:00 2001 From: Wanjohi Date: Tue, 28 Jan 2025 20:23:28 +0300 Subject: [PATCH] =?UTF-8?q?=E2=9D=8C=20revert(protobuf):=20Remove=20protob?= =?UTF-8?q?uf=20for=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 654 +++------------- buf.gen.yaml | 17 - bun.lockb | Bin 762856 -> 757560 bytes packages/input/package.json | 8 - packages/input/src/keyboard.ts | 73 +- packages/input/src/latency.ts | 7 +- packages/input/src/messages.ts | 36 + packages/input/src/mouse.ts | 117 +-- .../input/src/proto/latency_tracker_pb.ts | 60 -- packages/input/src/proto/messages_pb.ts | 62 -- packages/input/src/proto/types_pb.ts | 272 ------- packages/input/src/types.ts | 52 ++ packages/input/src/webrtc-stream.ts | 14 +- packages/relay/go.mod | 23 +- packages/relay/go.sum | 64 +- packages/relay/internal/datachannel.go | 24 +- packages/relay/internal/egress.go | 28 +- packages/relay/internal/http.go | 3 +- packages/relay/internal/ingest.go | 9 +- packages/relay/internal/latency.go | 80 +- packages/relay/internal/messages.go | 109 ++- .../internal/proto/latency_tracker.pb.go | 203 ----- packages/relay/internal/proto/messages.pb.go | 207 ----- packages/relay/internal/proto/types.pb.go | 713 ------------------ packages/relay/internal/websocket.go | 40 +- packages/server/Cargo.toml | 10 +- packages/server/src/args/app_args.rs | 5 +- packages/server/src/latency.rs | 2 +- packages/server/src/main.rs | 1 - packages/server/src/messages.rs | 69 +- packages/server/src/nestrisink/imp.rs | 179 +++-- packages/server/src/proto.rs | 1 - packages/server/src/proto/proto.rs | 139 ---- packages/server/src/websocket.rs | 29 +- protobufs/buf.yaml | 7 - protobufs/latency_tracker.proto | 17 - protobufs/messages.proto | 18 - protobufs/types.proto | 63 -- 38 files changed, 652 insertions(+), 2763 deletions(-) delete mode 100644 buf.gen.yaml delete mode 100644 packages/input/src/proto/latency_tracker_pb.ts delete mode 100644 packages/input/src/proto/messages_pb.ts delete mode 100644 packages/input/src/proto/types_pb.ts create mode 100644 packages/input/src/types.ts delete mode 100644 packages/relay/internal/proto/latency_tracker.pb.go delete mode 100644 packages/relay/internal/proto/messages.pb.go delete mode 100644 packages/relay/internal/proto/types.pb.go delete mode 100644 packages/server/src/proto.rs delete mode 100644 packages/server/src/proto/proto.rs delete mode 100644 protobufs/buf.yaml delete mode 100644 protobufs/latency_tracker.proto delete mode 100644 protobufs/messages.proto delete mode 100644 protobufs/types.proto diff --git a/Cargo.lock b/Cargo.lock index 9fd807b2..b16cadae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -978,6 +978,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -985,7 +994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "subtle", "zeroize", ] @@ -997,7 +1006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", + "rand_core", "typenum", ] @@ -1107,7 +1116,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "webrtc 0.11.0", + "webrtc", ] [[package]] @@ -1174,7 +1183,7 @@ dependencies = [ "hkdf", "pem-rfc7468", "pkcs8", - "rand_core 0.6.4", + "rand_core", "sec1", "subtle", "zeroize", @@ -1217,7 +1226,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -1233,6 +1242,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1378,22 +1397,10 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", -] - [[package]] name = "ghash" version = "0.5.1" @@ -1502,7 +1509,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -1555,11 +1562,11 @@ dependencies = [ "livekit-api", "livekit-protocol", "parse_link_header", - "rand 0.8.5", + "rand", "reqwest 0.11.27", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.3", "tokio", "tokio-native-tls", "tokio-stream", @@ -1586,7 +1593,7 @@ dependencies = [ "serde", "serde_json", "test-log", - "thiserror 2.0.11", + "thiserror 2.0.3", "tokio", "tokio-native-tls", "tracing", @@ -1627,7 +1634,7 @@ dependencies = [ "serde", "serde_bytes", "smallvec", - "thiserror 2.0.11", + "thiserror 2.0.3", ] [[package]] @@ -1796,7 +1803,7 @@ dependencies = [ "gstreamer", "gstreamer-app", "gstreamer-video", - "thiserror 2.0.11", + "thiserror 2.0.3", ] [[package]] @@ -1812,7 +1819,7 @@ dependencies = [ "gstreamer-video-sys", "libc", "serde", - "thiserror 2.0.11", + "thiserror 2.0.3", ] [[package]] @@ -2356,34 +2363,14 @@ dependencies = [ "bytes", "log", "portable-atomic", - "rand 0.8.5", - "rtcp 0.11.0", - "rtp 0.11.0", + "rand", + "rtcp", + "rtp", "thiserror 1.0.69", "tokio", "waitgroup", - "webrtc-srtp 0.13.0", - "webrtc-util 0.9.0", -] - -[[package]] -name = "interceptor" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ab04c530fd82e414e40394cabe5f0ebfe30d119f10fe29d6e3561926af412e" -dependencies = [ - "async-trait", - "bytes", - "log", - "portable-atomic", - "rand 0.8.5", - "rtcp 0.12.0", - "rtp 0.12.0", - "thiserror 1.0.69", - "tokio", - "waitgroup", - "webrtc-srtp 0.14.0", - "webrtc-util 0.10.0", + "webrtc-srtp", + "webrtc-util", ] [[package]] @@ -2523,7 +2510,7 @@ dependencies = [ "livekit-protocol", "log", "parking_lot", - "prost 0.12.6", + "prost", "reqwest 0.11.27", "scopeguard", "serde", @@ -2544,8 +2531,8 @@ dependencies = [ "parking_lot", "pbjson", "pbjson-types", - "prost 0.12.6", - "prost-types 0.12.6", + "prost", + "prost-types", "serde", "thiserror 1.0.69", "tokio", @@ -2639,7 +2626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.52.0", ] @@ -2696,6 +2683,7 @@ version = "0.1.0" dependencies = [ "chrono", "clap", + "flate2", "futures-util", "gst-plugin-webrtc", "gstreamer", @@ -2703,16 +2691,15 @@ dependencies = [ "log", "num-derive", "num-traits", - "prost 0.13.4", - "prost-types 0.13.4", - "rand 0.9.0", + "rand", "regex", "rustls 0.23.19", "serde", "serde_json", "tokio", - "tokio-tungstenite 0.26.1", - "webrtc 0.12.0", + "tokio-tungstenite 0.24.0", + "tokio-util", + "webrtc", ] [[package]] @@ -2994,8 +2981,8 @@ checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" dependencies = [ "heck 0.4.1", "itertools 0.11.0", - "prost 0.12.6", - "prost-types 0.12.6", + "prost", + "prost-types", ] [[package]] @@ -3008,7 +2995,7 @@ dependencies = [ "chrono", "pbjson", "pbjson-build", - "prost 0.12.6", + "prost", "prost-build", "serde", ] @@ -3126,7 +3113,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -3173,17 +3160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.6", -] - -[[package]] -name = "prost" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" -dependencies = [ - "bytes", - "prost-derive 0.13.4", + "prost-derive", ] [[package]] @@ -3200,8 +3177,8 @@ dependencies = [ "once_cell", "petgraph", "prettyplease", - "prost 0.12.6", - "prost-types 0.12.6", + "prost", + "prost-types", "regex", "syn 2.0.90", "tempfile", @@ -3220,35 +3197,13 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "prost-derive" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" -dependencies = [ - "anyhow", - "itertools 0.13.0", - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "prost-types" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost 0.12.6", -] - -[[package]] -name = "prost-types" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2f1e56baa61e93533aebc21af4d2134b70f66275e0fcdf3cbe43d77ff7e8fc" -dependencies = [ - "prost 0.13.4", + "prost", ] [[package]] @@ -3267,19 +3222,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.0", - "zerocopy 0.8.14", + "rand_chacha", + "rand_core", ] [[package]] @@ -3289,17 +3233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.0", + "rand_core", ] [[package]] @@ -3308,17 +3242,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "rand_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" -dependencies = [ - "getrandom 0.3.1", - "zerocopy 0.8.14", + "getrandom", ] [[package]] @@ -3495,7 +3419,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom", "libc", "spin", "untrusted", @@ -3510,18 +3434,7 @@ checksum = "fc9f775ff89c5fe7f0cc0abafb7c57688ae25ce688f1a52dd88e277616c76ab2" dependencies = [ "bytes", "thiserror 1.0.69", - "webrtc-util 0.9.0", -] - -[[package]] -name = "rtcp" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8306430fb118b7834bbee50e744dc34826eca1da2158657a3d6cbc70e24c2096" -dependencies = [ - "bytes", - "thiserror 1.0.69", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -3532,25 +3445,10 @@ checksum = "6870f09b5db96f8b9e7290324673259fd15519ebb7d55acf8e7eb044a9ead6af" dependencies = [ "bytes", "portable-atomic", - "rand 0.8.5", + "rand", "serde", "thiserror 1.0.69", - "webrtc-util 0.9.0", -] - -[[package]] -name = "rtp" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e68baca5b6cb4980678713f0d06ef3a432aa642baefcbfd0f4dd2ef9eb5ab550" -dependencies = [ - "bytes", - "memchr", - "portable-atomic", - "rand 0.8.5", - "serde", - "thiserror 1.0.69", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -3739,19 +3637,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13254db766b17451aced321e7397ebf0a446ef0c8d2942b6e67a95815421093f" dependencies = [ - "rand 0.8.5", - "substring", - "thiserror 1.0.69", - "url", -] - -[[package]] -name = "sdp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a526161f474ae94b966ba622379d939a8fe46c930eebbadb73e339622599d5" -dependencies = [ - "rand 0.8.5", + "rand", "substring", "thiserror 1.0.69", "url", @@ -3915,7 +3801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core", ] [[package]] @@ -3996,32 +3882,13 @@ dependencies = [ "crc", "lazy_static", "md-5", - "rand 0.8.5", + "rand", "ring", "subtle", "thiserror 1.0.69", "tokio", "url", - "webrtc-util 0.9.0", -] - -[[package]] -name = "stun" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea256fb46a13f9204e9dee9982997b2c3097db175a9fddaa8350310d03c4d5a3" -dependencies = [ - "base64 0.22.1", - "crc", - "lazy_static", - "md-5", - "rand 0.8.5", - "ring", - "subtle", - "thiserror 1.0.69", - "tokio", - "url", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -4205,11 +4072,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.3", ] [[package]] @@ -4225,9 +4092,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", @@ -4395,16 +4262,16 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.26.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" dependencies = [ "futures-util", "log", "native-tls", "tokio", "tokio-native-tls", - "tungstenite 0.26.1", + "tungstenite 0.24.0", ] [[package]] @@ -4541,7 +4408,7 @@ dependencies = [ "httparse", "log", "native-tls", - "rand 0.8.5", + "rand", "sha1", "thiserror 1.0.69", "url", @@ -4560,7 +4427,7 @@ dependencies = [ "http 1.1.0", "httparse", "log", - "rand 0.8.5", + "rand", "sha1", "thiserror 1.0.69", "url", @@ -4580,32 +4447,13 @@ dependencies = [ "httparse", "log", "native-tls", - "rand 0.8.5", + "rand", "sha1", "thiserror 1.0.69", "url", "utf-8", ] -[[package]] -name = "tungstenite" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.1.0", - "httparse", - "log", - "native-tls", - "rand 0.8.5", - "sha1", - "thiserror 2.0.11", - "utf-8", -] - [[package]] name = "turn" version = "0.8.0" @@ -4618,34 +4466,13 @@ dependencies = [ "log", "md-5", "portable-atomic", - "rand 0.8.5", + "rand", "ring", - "stun 0.6.0", + "stun", "thiserror 1.0.69", "tokio", "tokio-util", - "webrtc-util 0.9.0", -] - -[[package]] -name = "turn" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0044fdae001dd8a1e247ea6289abf12f4fcea1331a2364da512f9cd680bbd8cb" -dependencies = [ - "async-trait", - "base64 0.22.1", - "futures", - "log", - "md-5", - "portable-atomic", - "rand 0.8.5", - "ring", - "stun 0.7.0", - "thiserror 1.0.69", - "tokio", - "tokio-util", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -4744,7 +4571,7 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -4832,15 +4659,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasi" -version = "0.13.3+wasi-0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" -dependencies = [ - "wit-bindgen-rt", -] - [[package]] name = "wasm-bindgen" version = "0.2.97" @@ -4930,81 +4748,37 @@ dependencies = [ "bytes", "cfg-if", "hex", - "interceptor 0.12.0", + "interceptor", "lazy_static", "log", "portable-atomic", - "rand 0.8.5", + "rand", "rcgen", "regex", "ring", - "rtcp 0.11.0", - "rtp 0.11.0", + "rtcp", + "rtp", "rustls 0.23.19", - "sdp 0.6.2", + "sdp", "serde", "serde_json", "sha2", "smol_str", - "stun 0.6.0", + "stun", "thiserror 1.0.69", "time", "tokio", - "turn 0.8.0", + "turn", "url", "waitgroup", - "webrtc-data 0.9.0", - "webrtc-dtls 0.10.0", - "webrtc-ice 0.11.0", - "webrtc-mdns 0.7.0", - "webrtc-media 0.8.0", - "webrtc-sctp 0.10.0", - "webrtc-srtp 0.13.0", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30367074d9f18231d28a74fab0120856b2b665da108d71a12beab7185a36f97b" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "cfg-if", - "hex", - "interceptor 0.13.0", - "lazy_static", - "log", - "portable-atomic", - "rand 0.8.5", - "rcgen", - "regex", - "ring", - "rtcp 0.12.0", - "rtp 0.12.0", - "rustls 0.23.19", - "sdp 0.7.0", - "serde", - "serde_json", - "sha2", - "smol_str", - "stun 0.7.0", - "thiserror 1.0.69", - "time", - "tokio", - "turn 0.9.0", - "url", - "waitgroup", - "webrtc-data 0.10.0", - "webrtc-dtls 0.11.0", - "webrtc-ice 0.12.0", - "webrtc-mdns 0.8.0", - "webrtc-media 0.9.0", - "webrtc-sctp 0.11.0", - "webrtc-srtp 0.14.0", - "webrtc-util 0.10.0", + "webrtc-data", + "webrtc-dtls", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util", ] [[package]] @@ -5018,23 +4792,8 @@ dependencies = [ "portable-atomic", "thiserror 1.0.69", "tokio", - "webrtc-sctp 0.10.0", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc-data" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec93b991efcd01b73c5b3503fa8adba159d069abe5785c988ebe14fcf8f05d1" -dependencies = [ - "bytes", - "log", - "portable-atomic", - "thiserror 1.0.69", - "tokio", - "webrtc-sctp 0.11.0", - "webrtc-util 0.10.0", + "webrtc-sctp", + "webrtc-util", ] [[package]] @@ -5057,8 +4816,8 @@ dependencies = [ "p256", "p384", "portable-atomic", - "rand 0.8.5", - "rand_core 0.6.4", + "rand", + "rand_core", "rcgen", "ring", "rustls 0.23.19", @@ -5069,44 +4828,7 @@ dependencies = [ "subtle", "thiserror 1.0.69", "tokio", - "webrtc-util 0.9.0", - "x25519-dalek", - "x509-parser", -] - -[[package]] -name = "webrtc-dtls" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c9b89fc909f9da0499283b1112cd98f72fec28e55a54a9e352525ca65cd95c" -dependencies = [ - "aes", - "aes-gcm", - "async-trait", - "bincode", - "byteorder", - "cbc", - "ccm", - "der-parser 9.0.0", - "hkdf", - "hmac", - "log", - "p256", - "p384", - "portable-atomic", - "rand 0.8.5", - "rand_core 0.6.4", - "rcgen", - "ring", - "rustls 0.23.19", - "sec1", - "serde", - "sha1", - "sha2", - "subtle", - "thiserror 1.0.69", - "tokio", - "webrtc-util 0.10.0", + "webrtc-util", "x25519-dalek", "x509-parser", ] @@ -5122,43 +4844,18 @@ dependencies = [ "crc", "log", "portable-atomic", - "rand 0.8.5", + "rand", "serde", "serde_json", - "stun 0.6.0", + "stun", "thiserror 1.0.69", "tokio", - "turn 0.8.0", + "turn", "url", "uuid", "waitgroup", - "webrtc-mdns 0.7.0", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc-ice" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0348b28b593f7709ac98d872beb58c0009523df652c78e01b950ab9c537ff17d" -dependencies = [ - "arc-swap", - "async-trait", - "crc", - "log", - "portable-atomic", - "rand 0.8.5", - "serde", - "serde_json", - "stun 0.7.0", - "thiserror 1.0.69", - "tokio", - "turn 0.9.0", - "url", - "uuid", - "waitgroup", - "webrtc-mdns 0.8.0", - "webrtc-util 0.10.0", + "webrtc-mdns", + "webrtc-util", ] [[package]] @@ -5171,20 +4868,7 @@ dependencies = [ "socket2", "thiserror 1.0.69", "tokio", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc-mdns" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6dfe9686c6c9c51428da4de415cb6ca2dc0591ce2b63212e23fd9cccf0e316b" -dependencies = [ - "log", - "socket2", - "thiserror 1.0.69", - "tokio", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -5195,21 +4879,8 @@ checksum = "1c15b20e98167b22949abc1c20eca7c6d814307d187068fe7a48f0b87a4f6d46" dependencies = [ "byteorder", "bytes", - "rand 0.8.5", - "rtp 0.11.0", - "thiserror 1.0.69", -] - -[[package]] -name = "webrtc-media" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e153be16b8650021ad3e9e49ab6e5fa9fb7f6d1c23c213fd8bbd1a1135a4c704" -dependencies = [ - "byteorder", - "bytes", - "rand 0.8.5", - "rtp 0.12.0", + "rand", + "rtp", "thiserror 1.0.69", ] @@ -5225,28 +4896,10 @@ dependencies = [ "crc", "log", "portable-atomic", - "rand 0.8.5", + "rand", "thiserror 1.0.69", "tokio", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc-sctp" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5faf3846ec4b7e64b56338d62cbafe084aa79806b0379dff5cc74a8b7a2b3063" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "crc", - "log", - "portable-atomic", - "rand 0.8.5", - "thiserror 1.0.69", - "tokio", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -5263,36 +4916,13 @@ dependencies = [ "ctr", "hmac", "log", - "rtcp 0.11.0", - "rtp 0.11.0", + "rtcp", + "rtp", "sha1", "subtle", "thiserror 1.0.69", "tokio", - "webrtc-util 0.9.0", -] - -[[package]] -name = "webrtc-srtp" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771db9993712a8fb3886d5be4613ebf27250ef422bd4071988bf55f1ed1a64fa" -dependencies = [ - "aead", - "aes", - "aes-gcm", - "byteorder", - "bytes", - "ctr", - "hmac", - "log", - "rtcp 0.12.0", - "rtp 0.12.0", - "sha1", - "subtle", - "thiserror 1.0.69", - "tokio", - "webrtc-util 0.10.0", + "webrtc-util", ] [[package]] @@ -5310,28 +4940,7 @@ dependencies = [ "log", "nix 0.26.4", "portable-atomic", - "rand 0.8.5", - "thiserror 1.0.69", - "tokio", - "winapi", -] - -[[package]] -name = "webrtc-util" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1438a8fd0d69c5775afb4a71470af92242dbd04059c61895163aa3c1ef933375" -dependencies = [ - "async-trait", - "bitflags 1.3.2", - "bytes", - "ipnet", - "lazy_static", - "libc", - "log", - "nix 0.26.4", - "portable-atomic", - "rand 0.8.5", + "rand", "thiserror 1.0.69", "tokio", "winapi", @@ -5577,15 +5186,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "wit-bindgen-rt" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" -dependencies = [ - "bitflags 2.6.0", -] - [[package]] name = "write16" version = "1.0.0" @@ -5605,7 +5205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core", "serde", "zeroize", ] @@ -5674,16 +5274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468" -dependencies = [ - "zerocopy-derive 0.8.14", + "zerocopy-derive", ] [[package]] @@ -5697,17 +5288,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "zerocopy-derive" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "zerofrom" version = "0.1.5" diff --git a/buf.gen.yaml b/buf.gen.yaml deleted file mode 100644 index b420ec62..00000000 --- a/buf.gen.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: v2 -inputs: - - directory: protobufs -plugins: - # TypeScript (frontend) - - remote: buf.build/bufbuild/es - out: packages/input/src/proto - opt: target=ts - - # Golang (relay) - - remote: buf.build/protocolbuffers/go - out: packages/relay/internal/proto - opt: paths=source_relative - - # Rust (nestri-server) - - remote: buf.build/community/neoeinstein-prost - out: packages/server/src/proto diff --git a/bun.lockb b/bun.lockb index d3b27ed72852695008af23d48c13948bcfcdbced..6a396664a34a9c0ca71a7a8f13cde20b54c1f185 100755 GIT binary patch delta 20280 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 aZsF4KN#P4D&ws#k2by_hT(f22Oa2c(43G){ delta 25285 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 diff --git a/packages/input/package.json b/packages/input/package.json index 7ca12c4e..7a0f8c51 100644 --- a/packages/input/package.json +++ b/packages/input/package.json @@ -5,13 +5,5 @@ "sideEffects": false, "exports": { ".": "./src/index.ts" - }, - "devDependencies": { - "@bufbuild/buf": "^1.50.0", - "@bufbuild/protoc-gen-es": "^2.2.3" - }, - "dependencies": { - "@bufbuild/protobuf": "^2.2.3", - "protobuf": "^0.11.1" } } \ No newline at end of file diff --git a/packages/input/src/keyboard.ts b/packages/input/src/keyboard.ts index 8613826e..a5541e3d 100644 --- a/packages/input/src/keyboard.ts +++ b/packages/input/src/keyboard.ts @@ -1,17 +1,8 @@ +import {type Input} from "./types" import {keyCodeToLinuxEventCode} from "./codes" +import {MessageInput, encodeMessage} from "./messages"; import {WebRTCStream} from "./webrtc-stream"; import {LatencyTracker} from "./latency"; -import {ProtoLatencyTracker, ProtoTimestampEntry} from "./proto/latency_tracker_pb"; -import {timestampFromDate} from "@bufbuild/protobuf/wkt"; -import {ProtoMessageBase, ProtoMessageInput, ProtoMessageInputSchema} from "./proto/messages_pb"; -import { - ProtoInput, - ProtoInputSchema, - ProtoKeyDownSchema, - ProtoKeyUpSchema, - ProtoMouseMoveSchema -} from "./proto/types_pb"; -import {create, toBinary} from "@bufbuild/protobuf"; interface Props { webrtc: WebRTCStream; @@ -24,31 +15,19 @@ export class Keyboard { protected connected!: boolean; // Store references to event listeners - private readonly keydownListener: (e: KeyboardEvent) => void; - private readonly keyupListener: (e: KeyboardEvent) => void; + private keydownListener: (e: KeyboardEvent) => void; + private keyupListener: (e: KeyboardEvent) => void; constructor({webrtc, canvas}: Props) { this.wrtc = webrtc; this.canvas = canvas; - this.keydownListener = this.createKeyboardListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "keyDown", - value: create(ProtoKeyDownSchema, { - type: "KeyDown", - key: this.keyToVirtualKeyCode(e.code) - }), - } + this.keydownListener = this.createKeyboardListener("keydown", (e: any) => ({ + type: "KeyDown", + key: this.keyToVirtualKeyCode(e.code) })); - this.keyupListener = this.createKeyboardListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "keyUp", - value: create(ProtoKeyUpSchema, { - type: "KeyUp", - key: this.keyToVirtualKeyCode(e.code) - }), - } + this.keyupListener = this.createKeyboardListener("keyup", (e: any) => ({ + type: "KeyUp", + key: this.keyToVirtualKeyCode(e.code) })); this.run() } @@ -80,7 +59,7 @@ export class Keyboard { } // Helper function to create and return mouse listeners - private createKeyboardListener(dataCreator: (e: Event) => ProtoInput): (e: Event) => void { + private createKeyboardListener(type: string, dataCreator: (e: Event) => Partial): (e: Event) => void { return (e: Event) => { e.preventDefault(); e.stopPropagation(); @@ -88,34 +67,18 @@ export class Keyboard { if ((e as any).repeat) return; - const data = dataCreator(e as any); + const data = dataCreator(e as any); // type assertion because of the way dataCreator is used + const dataString = JSON.stringify({...data, type} as Input); // Latency tracking const tracker = new LatencyTracker("input-keyboard"); tracker.addTimestamp("client_send"); - const protoTracker: ProtoLatencyTracker = { - $typeName: "proto.ProtoLatencyTracker", - sequenceId: tracker.sequence_id, - timestamps: [], + const message: MessageInput = { + payload_type: "input", + data: dataString, + latency: tracker, }; - for (const t of tracker.timestamps) { - protoTracker.timestamps.push({ - $typeName: "proto.ProtoTimestampEntry", - stage: t.stage, - time: timestampFromDate(t.time), - } as ProtoTimestampEntry); - } - - const message: ProtoMessageInput = { - $typeName: "proto.ProtoMessageInput", - messageBase: { - $typeName: "proto.ProtoMessageBase", - payloadType: "input", - latency: protoTracker, - } as ProtoMessageBase, - data: data, - }; - this.wrtc.sendBinary(toBinary(ProtoMessageInputSchema, message)); + this.wrtc.sendBinary(encodeMessage(message)); }; } diff --git a/packages/input/src/latency.ts b/packages/input/src/latency.ts index 3c97ceb2..3a556896 100644 --- a/packages/input/src/latency.ts +++ b/packages/input/src/latency.ts @@ -6,10 +6,12 @@ type TimestampEntry = { export class LatencyTracker { sequence_id: string; timestamps: TimestampEntry[]; + metadata?: Record; - constructor(sequence_id: string, timestamps: TimestampEntry[] = []) { + constructor(sequence_id: string, timestamps: TimestampEntry[] = [], metadata: Record = {}) { this.sequence_id = sequence_id; this.timestamps = timestamps; + this.metadata = metadata; } addTimestamp(stage: string): void { @@ -38,6 +40,7 @@ export class LatencyTracker { // Fill nanoseconds with zeros to match the expected format time: entry.time.toISOString().replace(/\.(\d+)Z$/, ".$1000000Z"), })), + metadata: this.metadata, }; } @@ -46,6 +49,6 @@ export class LatencyTracker { stage: ts.stage, time: new Date(ts.time), })); - return new LatencyTracker(json.sequence_id, timestamps); + return new LatencyTracker(json.sequence_id, timestamps, json.metadata); } } diff --git a/packages/input/src/messages.ts b/packages/input/src/messages.ts index e7c235b6..5d60bf07 100644 --- a/packages/input/src/messages.ts +++ b/packages/input/src/messages.ts @@ -1,7 +1,13 @@ +import {gzip, ungzip} from "pako"; import {LatencyTracker} from "./latency"; export interface MessageBase { payload_type: string; +} + +export interface MessageInput extends MessageBase { + payload_type: "input"; + data: string; latency?: LatencyTracker; } @@ -35,3 +41,33 @@ export interface MessageAnswer extends MessageBase { payload_type: "answer"; answer_type: AnswerType; } + +function blobToUint8Array(blob: Blob): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + const arrayBuffer = reader.result as ArrayBuffer; + resolve(new Uint8Array(arrayBuffer)); + }; + reader.onerror = reject; + reader.readAsArrayBuffer(blob); + }); +} + +export function encodeMessage(message: T): Uint8Array { + // Convert the message to JSON string + const json = JSON.stringify(message); + // Compress the JSON string using gzip + return gzip(json); +} + +export async function decodeMessage(data: Blob): Promise { + // Convert the Blob to Uint8Array + const array = await blobToUint8Array(data); + // Decompress the gzip data + const decompressed = ungzip(array); + // Convert the Uint8Array to JSON string + const json = new TextDecoder().decode(decompressed); + // Parse the JSON string + return JSON.parse(json); +} diff --git a/packages/input/src/mouse.ts b/packages/input/src/mouse.ts index e1848b94..0345a522 100644 --- a/packages/input/src/mouse.ts +++ b/packages/input/src/mouse.ts @@ -1,18 +1,8 @@ +import {type Input} from "./types" +import {mouseButtonToLinuxEventCode} from "./codes" +import {MessageInput, encodeMessage} from "./messages"; import {WebRTCStream} from "./webrtc-stream"; import {LatencyTracker} from "./latency"; -import {ProtoMessageInput, ProtoMessageBase, ProtoMessageInputSchema} from "./proto/messages_pb"; -import { - ProtoInput, ProtoInputSchema, - ProtoMouseKeyDown, ProtoMouseKeyDownSchema, - ProtoMouseKeyUp, ProtoMouseKeyUpSchema, - ProtoMouseMove, - ProtoMouseMoveSchema, - ProtoMouseWheel, ProtoMouseWheelSchema -} from "./proto/types_pb"; -import {mouseButtonToLinuxEventCode} from "./codes"; -import {ProtoLatencyTracker, ProtoTimestampEntry} from "./proto/latency_tracker_pb"; -import {create, toBinary} from "@bufbuild/protobuf"; -import {timestampFromDate} from "@bufbuild/protobuf/wkt"; interface Props { webrtc: WebRTCStream; @@ -25,56 +15,33 @@ export class Mouse { protected connected!: boolean; // Store references to event listeners - private readonly mousemoveListener: (e: MouseEvent) => void; - private readonly mousedownListener: (e: MouseEvent) => void; - private readonly mouseupListener: (e: MouseEvent) => void; - private readonly mousewheelListener: (e: WheelEvent) => void; + private mousemoveListener: (e: MouseEvent) => void; + private mousedownListener: (e: MouseEvent) => void; + private mouseupListener: (e: MouseEvent) => void; + private mousewheelListener: (e: WheelEvent) => void; constructor({webrtc, canvas}: Props) { this.wrtc = webrtc; this.canvas = canvas; - this.mousemoveListener = this.createMouseListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "mouseMove", - value: create(ProtoMouseMoveSchema, { - type: "MouseMove", - x: e.movementX, - y: e.movementY - }), - } + this.mousemoveListener = this.createMouseListener("mousemove", (e: any) => ({ + type: "MouseMove", + x: e.movementX, + y: e.movementY })); - this.mousedownListener = this.createMouseListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "mouseKeyDown", - value: create(ProtoMouseKeyDownSchema, { - type: "MouseKeyDown", - key: this.keyToVirtualKeyCode(e.button) - }), - } + this.mousedownListener = this.createMouseListener("mousedown", (e: any) => ({ + type: "MouseKeyDown", + key: this.keyToVirtualKeyCode(e.button) })); - this.mouseupListener = this.createMouseListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "mouseKeyUp", - value: create(ProtoMouseKeyUpSchema, { - type: "MouseKeyUp", - key: this.keyToVirtualKeyCode(e.button) - }), - } + + this.mouseupListener = this.createMouseListener("mouseup", (e: any) => ({ + type: "MouseKeyUp", + key: this.keyToVirtualKeyCode(e.button) })); - this.mousewheelListener = this.createMouseListener((e: any) => create(ProtoInputSchema, { - $typeName: "proto.ProtoInput", - inputType: { - case: "mouseWheel", - value: create(ProtoMouseWheelSchema, { - type: "MouseWheel", - x: e.deltaX, - y: e.deltaY - }), - } + this.mousewheelListener = this.createMouseListener("wheel", (e: any) => ({ + type: "MouseWheel", + x: e.deltaX, + y: e.deltaY })); this.run() @@ -92,10 +59,10 @@ export class Mouse { if (document.pointerLockElement == this.canvas) { this.connected = true - this.canvas.addEventListener("mousemove", this.mousemoveListener, {passive: false}); - this.canvas.addEventListener("mousedown", this.mousedownListener, {passive: false}); - this.canvas.addEventListener("mouseup", this.mouseupListener, {passive: false}); - this.canvas.addEventListener("wheel", this.mousewheelListener, {passive: false}); + this.canvas.addEventListener("mousemove", this.mousemoveListener, { passive: false }); + this.canvas.addEventListener("mousedown", this.mousedownListener, { passive: false }); + this.canvas.addEventListener("mouseup", this.mouseupListener, { passive: false }); + this.canvas.addEventListener("wheel", this.mousewheelListener, { passive: false }); } else { if (this.connected) { @@ -114,38 +81,22 @@ export class Mouse { } // Helper function to create and return mouse listeners - private createMouseListener(dataCreator: (e: Event) => ProtoInput): (e: Event) => void { + private createMouseListener(type: string, dataCreator: (e: Event) => Partial): (e: Event) => void { return (e: Event) => { e.preventDefault(); e.stopPropagation(); - const data = dataCreator(e as any); + const data = dataCreator(e as any); // type assertion because of the way dataCreator is used + const dataString = JSON.stringify({...data, type} as Input); // Latency tracking const tracker = new LatencyTracker("input-mouse"); tracker.addTimestamp("client_send"); - const protoTracker: ProtoLatencyTracker = { - $typeName: "proto.ProtoLatencyTracker", - sequenceId: tracker.sequence_id, - timestamps: [], + const message: MessageInput = { + payload_type: "input", + data: dataString, + latency: tracker, }; - for (const t of tracker.timestamps) { - protoTracker.timestamps.push({ - $typeName: "proto.ProtoTimestampEntry", - stage: t.stage, - time: timestampFromDate(t.time), - } as ProtoTimestampEntry); - } - - const message: ProtoMessageInput = { - $typeName: "proto.ProtoMessageInput", - messageBase: { - $typeName: "proto.ProtoMessageBase", - payloadType: "input", - latency: protoTracker, - } as ProtoMessageBase, - data: data, - }; - this.wrtc.sendBinary(toBinary(ProtoMessageInputSchema, message)); + this.wrtc.sendBinary(encodeMessage(message)); }; } diff --git a/packages/input/src/proto/latency_tracker_pb.ts b/packages/input/src/proto/latency_tracker_pb.ts deleted file mode 100644 index f3d94771..00000000 --- a/packages/input/src/proto/latency_tracker_pb.ts +++ /dev/null @@ -1,60 +0,0 @@ -// @generated by protoc-gen-es v2.2.3 with parameter "target=ts" -// @generated from file latency_tracker.proto (package proto, syntax proto3) -/* eslint-disable */ - -import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; -import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; -import type { Timestamp } from "@bufbuild/protobuf/wkt"; -import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; -import type { Message } from "@bufbuild/protobuf"; - -/** - * Describes the file latency_tracker.proto. - */ -export const file_latency_tracker: GenFile = /*@__PURE__*/ - fileDesc("ChVsYXRlbmN5X3RyYWNrZXIucHJvdG8SBXByb3RvIk4KE1Byb3RvVGltZXN0YW1wRW50cnkSDQoFc3RhZ2UYASABKAkSKAoEdGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiWgoTUHJvdG9MYXRlbmN5VHJhY2tlchITCgtzZXF1ZW5jZV9pZBgBIAEoCRIuCgp0aW1lc3RhbXBzGAIgAygLMhoucHJvdG8uUHJvdG9UaW1lc3RhbXBFbnRyeUIWWhRyZWxheS9pbnRlcm5hbC9wcm90b2IGcHJvdG8z", [file_google_protobuf_timestamp]); - -/** - * @generated from message proto.ProtoTimestampEntry - */ -export type ProtoTimestampEntry = Message<"proto.ProtoTimestampEntry"> & { - /** - * @generated from field: string stage = 1; - */ - stage: string; - - /** - * @generated from field: google.protobuf.Timestamp time = 2; - */ - time?: Timestamp; -}; - -/** - * Describes the message proto.ProtoTimestampEntry. - * Use `create(ProtoTimestampEntrySchema)` to create a new message. - */ -export const ProtoTimestampEntrySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_latency_tracker, 0); - -/** - * @generated from message proto.ProtoLatencyTracker - */ -export type ProtoLatencyTracker = Message<"proto.ProtoLatencyTracker"> & { - /** - * @generated from field: string sequence_id = 1; - */ - sequenceId: string; - - /** - * @generated from field: repeated proto.ProtoTimestampEntry timestamps = 2; - */ - timestamps: ProtoTimestampEntry[]; -}; - -/** - * Describes the message proto.ProtoLatencyTracker. - * Use `create(ProtoLatencyTrackerSchema)` to create a new message. - */ -export const ProtoLatencyTrackerSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_latency_tracker, 1); - diff --git a/packages/input/src/proto/messages_pb.ts b/packages/input/src/proto/messages_pb.ts deleted file mode 100644 index 0b918b94..00000000 --- a/packages/input/src/proto/messages_pb.ts +++ /dev/null @@ -1,62 +0,0 @@ -// @generated by protoc-gen-es v2.2.3 with parameter "target=ts" -// @generated from file messages.proto (package proto, syntax proto3) -/* eslint-disable */ - -import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; -import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; -import type { ProtoInput } from "./types_pb"; -import { file_types } from "./types_pb"; -import type { ProtoLatencyTracker } from "./latency_tracker_pb"; -import { file_latency_tracker } from "./latency_tracker_pb"; -import type { Message } from "@bufbuild/protobuf"; - -/** - * Describes the file messages.proto. - */ -export const file_messages: GenFile = /*@__PURE__*/ - fileDesc("Cg5tZXNzYWdlcy5wcm90bxIFcHJvdG8iVQoQUHJvdG9NZXNzYWdlQmFzZRIUCgxwYXlsb2FkX3R5cGUYASABKAkSKwoHbGF0ZW5jeRgCIAEoCzIaLnByb3RvLlByb3RvTGF0ZW5jeVRyYWNrZXIiYwoRUHJvdG9NZXNzYWdlSW5wdXQSLQoMbWVzc2FnZV9iYXNlGAEgASgLMhcucHJvdG8uUHJvdG9NZXNzYWdlQmFzZRIfCgRkYXRhGAIgASgLMhEucHJvdG8uUHJvdG9JbnB1dEIWWhRyZWxheS9pbnRlcm5hbC9wcm90b2IGcHJvdG8z", [file_types, file_latency_tracker]); - -/** - * @generated from message proto.ProtoMessageBase - */ -export type ProtoMessageBase = Message<"proto.ProtoMessageBase"> & { - /** - * @generated from field: string payload_type = 1; - */ - payloadType: string; - - /** - * @generated from field: proto.ProtoLatencyTracker latency = 2; - */ - latency?: ProtoLatencyTracker; -}; - -/** - * Describes the message proto.ProtoMessageBase. - * Use `create(ProtoMessageBaseSchema)` to create a new message. - */ -export const ProtoMessageBaseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_messages, 0); - -/** - * @generated from message proto.ProtoMessageInput - */ -export type ProtoMessageInput = Message<"proto.ProtoMessageInput"> & { - /** - * @generated from field: proto.ProtoMessageBase message_base = 1; - */ - messageBase?: ProtoMessageBase; - - /** - * @generated from field: proto.ProtoInput data = 2; - */ - data?: ProtoInput; -}; - -/** - * Describes the message proto.ProtoMessageInput. - * Use `create(ProtoMessageInputSchema)` to create a new message. - */ -export const ProtoMessageInputSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_messages, 1); - diff --git a/packages/input/src/proto/types_pb.ts b/packages/input/src/proto/types_pb.ts deleted file mode 100644 index 689bdc1f..00000000 --- a/packages/input/src/proto/types_pb.ts +++ /dev/null @@ -1,272 +0,0 @@ -// @generated by protoc-gen-es v2.2.3 with parameter "target=ts" -// @generated from file types.proto (package proto, syntax proto3) -/* eslint-disable */ - -import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; -import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; -import type { Message } from "@bufbuild/protobuf"; - -/** - * Describes the file types.proto. - */ -export const file_types: GenFile = /*@__PURE__*/ - fileDesc("Cgt0eXBlcy5wcm90bxIFcHJvdG8iNAoOUHJvdG9Nb3VzZU1vdmUSDAoEdHlwZRgBIAEoCRIJCgF4GAIgASgFEgkKAXkYAyABKAUiNwoRUHJvdG9Nb3VzZU1vdmVBYnMSDAoEdHlwZRgBIAEoCRIJCgF4GAIgASgFEgkKAXkYAyABKAUiNQoPUHJvdG9Nb3VzZVdoZWVsEgwKBHR5cGUYASABKAkSCQoBeBgCIAEoBRIJCgF5GAMgASgFIi4KEVByb3RvTW91c2VLZXlEb3duEgwKBHR5cGUYASABKAkSCwoDa2V5GAIgASgFIiwKD1Byb3RvTW91c2VLZXlVcBIMCgR0eXBlGAEgASgJEgsKA2tleRgCIAEoBSIpCgxQcm90b0tleURvd24SDAoEdHlwZRgBIAEoCRILCgNrZXkYAiABKAUiJwoKUHJvdG9LZXlVcBIMCgR0eXBlGAEgASgJEgsKA2tleRgCIAEoBSLcAgoKUHJvdG9JbnB1dBIrCgptb3VzZV9tb3ZlGAEgASgLMhUucHJvdG8uUHJvdG9Nb3VzZU1vdmVIABIyCg5tb3VzZV9tb3ZlX2FicxgCIAEoCzIYLnByb3RvLlByb3RvTW91c2VNb3ZlQWJzSAASLQoLbW91c2Vfd2hlZWwYAyABKAsyFi5wcm90by5Qcm90b01vdXNlV2hlZWxIABIyCg5tb3VzZV9rZXlfZG93bhgEIAEoCzIYLnByb3RvLlByb3RvTW91c2VLZXlEb3duSAASLgoMbW91c2Vfa2V5X3VwGAUgASgLMhYucHJvdG8uUHJvdG9Nb3VzZUtleVVwSAASJwoIa2V5X2Rvd24YBiABKAsyEy5wcm90by5Qcm90b0tleURvd25IABIjCgZrZXlfdXAYByABKAsyES5wcm90by5Qcm90b0tleVVwSABCDAoKaW5wdXRfdHlwZUIWWhRyZWxheS9pbnRlcm5hbC9wcm90b2IGcHJvdG8z"); - -/** - * MouseMove message - * - * @generated from message proto.ProtoMouseMove - */ -export type ProtoMouseMove = Message<"proto.ProtoMouseMove"> & { - /** - * Fixed value "MouseMove" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 x = 2; - */ - x: number; - - /** - * @generated from field: int32 y = 3; - */ - y: number; -}; - -/** - * Describes the message proto.ProtoMouseMove. - * Use `create(ProtoMouseMoveSchema)` to create a new message. - */ -export const ProtoMouseMoveSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 0); - -/** - * MouseMoveAbs message - * - * @generated from message proto.ProtoMouseMoveAbs - */ -export type ProtoMouseMoveAbs = Message<"proto.ProtoMouseMoveAbs"> & { - /** - * Fixed value "MouseMoveAbs" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 x = 2; - */ - x: number; - - /** - * @generated from field: int32 y = 3; - */ - y: number; -}; - -/** - * Describes the message proto.ProtoMouseMoveAbs. - * Use `create(ProtoMouseMoveAbsSchema)` to create a new message. - */ -export const ProtoMouseMoveAbsSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 1); - -/** - * MouseWheel message - * - * @generated from message proto.ProtoMouseWheel - */ -export type ProtoMouseWheel = Message<"proto.ProtoMouseWheel"> & { - /** - * Fixed value "MouseWheel" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 x = 2; - */ - x: number; - - /** - * @generated from field: int32 y = 3; - */ - y: number; -}; - -/** - * Describes the message proto.ProtoMouseWheel. - * Use `create(ProtoMouseWheelSchema)` to create a new message. - */ -export const ProtoMouseWheelSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 2); - -/** - * MouseKeyDown message - * - * @generated from message proto.ProtoMouseKeyDown - */ -export type ProtoMouseKeyDown = Message<"proto.ProtoMouseKeyDown"> & { - /** - * Fixed value "MouseKeyDown" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 key = 2; - */ - key: number; -}; - -/** - * Describes the message proto.ProtoMouseKeyDown. - * Use `create(ProtoMouseKeyDownSchema)` to create a new message. - */ -export const ProtoMouseKeyDownSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 3); - -/** - * MouseKeyUp message - * - * @generated from message proto.ProtoMouseKeyUp - */ -export type ProtoMouseKeyUp = Message<"proto.ProtoMouseKeyUp"> & { - /** - * Fixed value "MouseKeyUp" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 key = 2; - */ - key: number; -}; - -/** - * Describes the message proto.ProtoMouseKeyUp. - * Use `create(ProtoMouseKeyUpSchema)` to create a new message. - */ -export const ProtoMouseKeyUpSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 4); - -/** - * KeyDown message - * - * @generated from message proto.ProtoKeyDown - */ -export type ProtoKeyDown = Message<"proto.ProtoKeyDown"> & { - /** - * Fixed value "KeyDown" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 key = 2; - */ - key: number; -}; - -/** - * Describes the message proto.ProtoKeyDown. - * Use `create(ProtoKeyDownSchema)` to create a new message. - */ -export const ProtoKeyDownSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 5); - -/** - * KeyUp message - * - * @generated from message proto.ProtoKeyUp - */ -export type ProtoKeyUp = Message<"proto.ProtoKeyUp"> & { - /** - * Fixed value "KeyUp" - * - * @generated from field: string type = 1; - */ - type: string; - - /** - * @generated from field: int32 key = 2; - */ - key: number; -}; - -/** - * Describes the message proto.ProtoKeyUp. - * Use `create(ProtoKeyUpSchema)` to create a new message. - */ -export const ProtoKeyUpSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 6); - -/** - * Union of all Input types - * - * @generated from message proto.ProtoInput - */ -export type ProtoInput = Message<"proto.ProtoInput"> & { - /** - * @generated from oneof proto.ProtoInput.input_type - */ - inputType: { - /** - * @generated from field: proto.ProtoMouseMove mouse_move = 1; - */ - value: ProtoMouseMove; - case: "mouseMove"; - } | { - /** - * @generated from field: proto.ProtoMouseMoveAbs mouse_move_abs = 2; - */ - value: ProtoMouseMoveAbs; - case: "mouseMoveAbs"; - } | { - /** - * @generated from field: proto.ProtoMouseWheel mouse_wheel = 3; - */ - value: ProtoMouseWheel; - case: "mouseWheel"; - } | { - /** - * @generated from field: proto.ProtoMouseKeyDown mouse_key_down = 4; - */ - value: ProtoMouseKeyDown; - case: "mouseKeyDown"; - } | { - /** - * @generated from field: proto.ProtoMouseKeyUp mouse_key_up = 5; - */ - value: ProtoMouseKeyUp; - case: "mouseKeyUp"; - } | { - /** - * @generated from field: proto.ProtoKeyDown key_down = 6; - */ - value: ProtoKeyDown; - case: "keyDown"; - } | { - /** - * @generated from field: proto.ProtoKeyUp key_up = 7; - */ - value: ProtoKeyUp; - case: "keyUp"; - } | { case: undefined; value?: undefined }; -}; - -/** - * Describes the message proto.ProtoInput. - * Use `create(ProtoInputSchema)` to create a new message. - */ -export const ProtoInputSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_types, 7); - diff --git a/packages/input/src/types.ts b/packages/input/src/types.ts new file mode 100644 index 00000000..b733b499 --- /dev/null +++ b/packages/input/src/types.ts @@ -0,0 +1,52 @@ +interface BaseInput { + timestamp?: number; // Add a timestamp for better context (optional) +} + +interface MouseMove extends BaseInput { + type: "MouseMove"; + x: number; + y: number; +} + +interface MouseMoveAbs extends BaseInput { + type: "MouseMoveAbs"; + x: number; + y: number; +} + +interface MouseWheel extends BaseInput { + type: "MouseWheel"; + x: number; + y: number; +} + +interface MouseKeyDown extends BaseInput { + type: "MouseKeyDown"; + key: number; +} + +interface MouseKeyUp extends BaseInput { + type: "MouseKeyUp"; + key: number; +} + +interface KeyDown extends BaseInput { + type: "KeyDown"; + key: number; +} + +interface KeyUp extends BaseInput { + type: "KeyUp"; + key: number; +} + + +export type Input = + | MouseMove + | MouseMoveAbs + | MouseWheel + | MouseKeyDown + | MouseKeyUp + | KeyDown + | KeyUp; + diff --git a/packages/input/src/webrtc-stream.ts b/packages/input/src/webrtc-stream.ts index da9b7a77..ea262092 100644 --- a/packages/input/src/webrtc-stream.ts +++ b/packages/input/src/webrtc-stream.ts @@ -6,6 +6,8 @@ import { MessageAnswer, JoinerType, AnswerType, + decodeMessage, + encodeMessage } from "./messages"; export class WebRTCStream { @@ -38,16 +40,16 @@ export class WebRTCStream { payload_type: "join", joiner_type: JoinerType.JoinerClient }; - this._ws!.send(JSON.stringify(joinMessage)); + this._ws!.send(encodeMessage(joinMessage)); } let iceHolder: RTCIceCandidateInit[] = []; this._ws.onmessage = async (e) => { - // allow only JSON - if (typeof e.data === "object") return; + // allow only binary + if (typeof e.data !== "object") return; if (!e.data) return; - const message = JSON.parse(e.data) as MessageBase; + const message = await decodeMessage(e.data); switch (message.payload_type) { case "sdp": if (!this._pc) { @@ -61,7 +63,7 @@ export class WebRTCStream { // Force stereo in Chromium browsers answer.sdp = this.forceOpusStereo(answer.sdp!); await this._pc!.setLocalDescription(answer); - this._ws!.send(JSON.stringify({ + this._ws!.send(encodeMessage({ payload_type: "sdp", sdp: answer })); @@ -152,7 +154,7 @@ export class WebRTCStream { payload_type: "ice", candidate: e.candidate }; - this._ws!.send(JSON.stringify(message)); + this._ws!.send(encodeMessage(message)); } } diff --git a/packages/relay/go.mod b/packages/relay/go.mod index 2657da28..8b21b568 100644 --- a/packages/relay/go.mod +++ b/packages/relay/go.mod @@ -6,27 +6,26 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/pion/interceptor v0.1.37 - github.com/pion/webrtc/v4 v4.0.8 - google.golang.org/protobuf v1.36.4 + github.com/pion/webrtc/v4 v4.0.2 ) require ( - github.com/pion/datachannel v1.5.10 // indirect + github.com/pion/datachannel v1.5.9 // indirect github.com/pion/dtls/v3 v3.0.4 // indirect - github.com/pion/ice/v4 v4.0.5 // indirect - github.com/pion/logging v0.2.3 // indirect + github.com/pion/ice/v4 v4.0.2 // indirect + github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns/v2 v2.0.7 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.15 // indirect - github.com/pion/rtp v1.8.11 // indirect - github.com/pion/sctp v1.8.35 // indirect - github.com/pion/sdp/v3 v3.0.10 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.34 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v3 v3.0.4 // indirect github.com/pion/stun/v3 v3.0.0 // indirect github.com/pion/transport/v3 v3.0.7 // indirect github.com/pion/turn/v4 v4.0.0 // indirect github.com/wlynxg/anet v0.0.5 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.28.0 // indirect ) diff --git a/packages/relay/go.sum b/packages/relay/go.sum index 56976d55..948b0702 100644 --- a/packages/relay/go.sum +++ b/packages/relay/go.sum @@ -1,33 +1,32 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/pion/datachannel v1.5.10 h1:ly0Q26K1i6ZkGf42W7D4hQYR90pZwzFOjTq5AuCKk4o= -github.com/pion/datachannel v1.5.10/go.mod h1:p/jJfC9arb29W7WrxyKbepTU20CFgyx5oLo8Rs4Py/M= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v3 v3.0.4 h1:44CZekewMzfrn9pmGrj5BNnTMDCFwr+6sLH+cCuLM7U= github.com/pion/dtls/v3 v3.0.4/go.mod h1:R373CsjxWqNPf6MEkfdy3aSe9niZvL/JaKlGeFphtMg= -github.com/pion/ice/v4 v4.0.5 h1:6awVfa1jg9YsI9/Lep4TG/o3kwS1Oayr5b8xz50ibJ8= -github.com/pion/ice/v4 v4.0.5/go.mod h1:JJaoEIxUIlGDA9gaRZbwXYqI3j6VG/QchpjX+QmwN6A= +github.com/pion/ice/v4 v4.0.2 h1:1JhBRX8iQLi0+TfcavTjPjI6GO41MFn4CeTBX+Y9h5s= +github.com/pion/ice/v4 v4.0.2/go.mod h1:DCdqyzgtsDNYN6/3U8044j3U7qsJ9KFJC92VnOWHvXg= github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= -github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI= -github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns/v2 v2.0.7 h1:c9kM8ewCgjslaAmicYMFQIde2H9/lrZpjBkN8VwoVtM= github.com/pion/mdns/v2 v2.0.7/go.mod h1:vAdSYNAT0Jy3Ru0zl2YiW3Rm/fJCwIeM0nToenfOJKA= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.15 h1:LZQi2JbdipLOj4eBjK4wlVoQWfrZbh3Q6eHtWtJBZBo= -github.com/pion/rtcp v1.2.15/go.mod h1:jlGuAjHMEXwMUHK78RgX0UmEJFV4zUKOFHR7OP+D3D0= -github.com/pion/rtp v1.8.11 h1:17xjnY5WO5hgO6SD3/NTIUPvSFw/PbLsIJyz1r1yNIk= -github.com/pion/rtp v1.8.11/go.mod h1:8uMBJj32Pa1wwx8Fuv/AsFhn8jsgw+3rUC2PfoBZ8p4= -github.com/pion/sctp v1.8.35 h1:qwtKvNK1Wc5tHMIYgTDJhfZk7vATGVHhXbUDfHbYwzA= -github.com/pion/sctp v1.8.35/go.mod h1:EcXP8zCYVTRy3W9xtOF7wJm1L1aXfKRQzaM33SjQlzg= -github.com/pion/sdp/v3 v3.0.10 h1:6MChLE/1xYB+CjumMw+gZ9ufp2DPApuVSnDT8t5MIgA= -github.com/pion/sdp/v3 v3.0.10/go.mod h1:88GMahN5xnScv1hIMTqLdu/cOcUkj6a9ytbncwMCq2E= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.34 h1:rCuD3m53i0oGxCSp7FLQKvqVx0Nf5AUAHhMRXTTQjBc= +github.com/pion/sctp v1.8.34/go.mod h1:yWkCClkXlzVW7BXfI2PjrUGBwUI0CjXJBkhLt+sdo4U= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v3 v3.0.4 h1:2Z6vDVxzrX3UHEgrUyIGM4rRouoC7v+NiF1IHtp9B5M= github.com/pion/srtp/v3 v3.0.4/go.mod h1:1Jx3FwDoxpRaTh1oRV8A/6G1BnFL+QI82eK4ms8EEJQ= github.com/pion/stun/v3 v3.0.0 h1:4h1gwhWLWuZWOJIJR9s2ferRO+W3zA/b6ijOI6mKzUw= @@ -36,23 +35,28 @@ github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1 github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM= github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA= -github.com/pion/webrtc/v4 v4.0.8 h1:T1ZmnT9qxIJIt4d8XoiMOBrTClGHDDXNg9e/fh018Qc= -github.com/pion/webrtc/v4 v4.0.8/go.mod h1:HHBeUVBAC+j4ZFnYhovEFStF02Arb1EyD4G7e7HBTJw= +github.com/pion/webrtc/v4 v4.0.2 h1:fBwm5/hqSUybrCWl0DDBSTDrpbkcgkqpeLmXw9CsBQA= +github.com/pion/webrtc/v4 v4.0.2/go.mod h1:moylBT2A4dNoEaYBCdV1nThM3TLwRHzWszIG+eSPaqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/packages/relay/internal/datachannel.go b/packages/relay/internal/datachannel.go index ae902f00..ba59fff8 100644 --- a/packages/relay/internal/datachannel.go +++ b/packages/relay/internal/datachannel.go @@ -2,22 +2,20 @@ package relay import ( "github.com/pion/webrtc/v4" - "google.golang.org/protobuf/proto" "log" - gen "relay/internal/proto" ) // NestriDataChannel is a custom data channel with callbacks type NestriDataChannel struct { *webrtc.DataChannel - callbacks map[string]OnMessageCallback // MessageBase type -> callback + binaryCallbacks map[string]OnMessageCallback // MessageBase type -> callback } // NewNestriDataChannel creates a new NestriDataChannel from *webrtc.DataChannel func NewNestriDataChannel(dc *webrtc.DataChannel) *NestriDataChannel { ndc := &NestriDataChannel{ - DataChannel: dc, - callbacks: make(map[string]OnMessageCallback), + DataChannel: dc, + binaryCallbacks: make(map[string]OnMessageCallback), } // Handler for incoming messages @@ -28,14 +26,14 @@ func NewNestriDataChannel(dc *webrtc.DataChannel) *NestriDataChannel { } // Decode message - var base gen.ProtoMessageInput - if err := proto.Unmarshal(msg.Data, &base); err != nil { + var base MessageBase + if err := DecodeMessage(msg.Data, &base); err != nil { log.Printf("Failed to decode binary DataChannel message, reason: %s\n", err) return } // Handle message type callback - if callback, ok := ndc.callbacks["input"]; ok { + if callback, ok := ndc.binaryCallbacks[base.PayloadType]; ok { go callback(msg.Data) } // TODO: Log unknown message type? }) @@ -50,16 +48,16 @@ func (ndc *NestriDataChannel) SendBinary(data []byte) error { // RegisterMessageCallback registers a callback for a given binary message type func (ndc *NestriDataChannel) RegisterMessageCallback(msgType string, callback OnMessageCallback) { - if ndc.callbacks == nil { - ndc.callbacks = make(map[string]OnMessageCallback) + if ndc.binaryCallbacks == nil { + ndc.binaryCallbacks = make(map[string]OnMessageCallback) } - ndc.callbacks[msgType] = callback + ndc.binaryCallbacks[msgType] = callback } // UnregisterMessageCallback removes the callback for a given binary message type func (ndc *NestriDataChannel) UnregisterMessageCallback(msgType string) { - if ndc.callbacks != nil { - delete(ndc.callbacks, msgType) + if ndc.binaryCallbacks != nil { + delete(ndc.binaryCallbacks, msgType) } } diff --git a/packages/relay/internal/egress.go b/packages/relay/internal/egress.go index 712f0fde..c72ce201 100644 --- a/packages/relay/internal/egress.go +++ b/packages/relay/internal/egress.go @@ -1,11 +1,8 @@ package relay import ( - "encoding/json" "github.com/pion/webrtc/v4" - "google.golang.org/protobuf/proto" "log" - gen "relay/internal/proto" ) func participantHandler(participant *Participant, room *Room) { @@ -57,22 +54,15 @@ func participantHandler(participant *Participant, room *Room) { if room.DataChannel != nil { // If debug mode, decode and add our timestamp, otherwise just send to room if GetFlags().Debug { - var inputMsg gen.ProtoMessageInput - if err = proto.Unmarshal(data, &inputMsg); err != nil { + var inputMsg MessageInput + if err = DecodeMessage(data, &inputMsg); err != nil { log.Printf("Failed to decode input message from participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) return } - - protoLat := inputMsg.GetMessageBase().GetLatency() - if protoLat != nil { - lat := LatencyTrackerFromProto(protoLat) - lat.AddTimestamp("relay_to_node") - protoLat = lat.ToProto() - } - - // Marshal and send - if data, err = proto.Marshal(&inputMsg); err != nil { - log.Printf("Failed to marshal input message for participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) + inputMsg.LatencyTracker.AddTimestamp("relay_to_node") + // Encode and send + if data, err = EncodeMessage(inputMsg); err != nil { + log.Printf("Failed to encode input message for participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) return } if err = room.DataChannel.SendBinary(data); err != nil { @@ -104,7 +94,7 @@ func participantHandler(participant *Participant, room *Room) { // ICE callback participant.WebSocket.RegisterMessageCallback("ice", func(data []byte) { var iceMsg MessageICECandidate - if err = json.Unmarshal(data, &iceMsg); err != nil { + if err = DecodeMessage(data, &iceMsg); err != nil { log.Printf("Failed to decode ICE message from participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) return } @@ -130,7 +120,7 @@ func participantHandler(participant *Participant, room *Room) { // SDP answer callback participant.WebSocket.RegisterMessageCallback("sdp", func(data []byte) { var sdpMsg MessageSDP - if err = json.Unmarshal(data, &sdpMsg); err != nil { + if err = DecodeMessage(data, &sdpMsg); err != nil { log.Printf("Failed to decode SDP message from participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) return } @@ -140,7 +130,7 @@ func participantHandler(participant *Participant, room *Room) { // Log callback participant.WebSocket.RegisterMessageCallback("log", func(data []byte) { var logMsg MessageLog - if err = json.Unmarshal(data, &logMsg); err != nil { + if err = DecodeMessage(data, &logMsg); err != nil { log.Printf("Failed to decode log message from participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err) return } diff --git a/packages/relay/internal/http.go b/packages/relay/internal/http.go index 2012d000..7ab89d0b 100644 --- a/packages/relay/internal/http.go +++ b/packages/relay/internal/http.go @@ -1,7 +1,6 @@ package relay import ( - "encoding/json" "github.com/gorilla/websocket" "log" "net/http" @@ -82,7 +81,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) { // Assign message handler for join request ws.RegisterMessageCallback("join", func(data []byte) { var joinMsg MessageJoin - if err = json.Unmarshal(data, &joinMsg); err != nil { + if err = DecodeMessage(data, &joinMsg); err != nil { log.Printf("Failed to decode join message: %s\n", err) return } diff --git a/packages/relay/internal/ingest.go b/packages/relay/internal/ingest.go index f3b6a085..2053e398 100644 --- a/packages/relay/internal/ingest.go +++ b/packages/relay/internal/ingest.go @@ -1,7 +1,6 @@ package relay import ( - "encoding/json" "errors" "fmt" "github.com/pion/webrtc/v4" @@ -135,7 +134,7 @@ func ingestHandler(room *Room) { // ICE callback room.WebSocket.RegisterMessageCallback("ice", func(data []byte) { var iceMsg MessageICECandidate - if err = json.Unmarshal(data, &iceMsg); err != nil { + if err = DecodeMessage(data, &iceMsg); err != nil { log.Printf("Failed to decode ICE candidate message from ingest for room: '%s' - reason: %s\n", room.Name, err) return } @@ -166,7 +165,7 @@ func ingestHandler(room *Room) { // SDP offer callback room.WebSocket.RegisterMessageCallback("sdp", func(data []byte) { var sdpMsg MessageSDP - if err = json.Unmarshal(data, &sdpMsg); err != nil { + if err = DecodeMessage(data, &sdpMsg); err != nil { log.Printf("Failed to decode SDP message from ingest for room: '%s' - reason: %s\n", room.Name, err) return } @@ -183,7 +182,7 @@ func ingestHandler(room *Room) { // Log callback room.WebSocket.RegisterMessageCallback("log", func(data []byte) { var logMsg MessageLog - if err = json.Unmarshal(data, &logMsg); err != nil { + if err = DecodeMessage(data, &logMsg); err != nil { log.Printf("Failed to decode log message from ingest for room: '%s' - reason: %s\n", room.Name, err) return } @@ -193,7 +192,7 @@ func ingestHandler(room *Room) { // Metrics callback room.WebSocket.RegisterMessageCallback("metrics", func(data []byte) { var metricsMsg MessageMetrics - if err = json.Unmarshal(data, &metricsMsg); err != nil { + if err = DecodeMessage(data, &metricsMsg); err != nil { log.Printf("Failed to decode metrics message from ingest for room: '%s' - reason: %s\n", room.Name, err) return } diff --git a/packages/relay/internal/latency.go b/packages/relay/internal/latency.go index 152f3492..9ebc31e1 100644 --- a/packages/relay/internal/latency.go +++ b/packages/relay/internal/latency.go @@ -2,21 +2,20 @@ package relay import ( "fmt" - "google.golang.org/protobuf/types/known/timestamppb" - gen "relay/internal/proto" "time" ) type TimestampEntry struct { - Stage string `json:"stage"` - Time time.Time `json:"time"` + Stage string `json:"stage"` + Time string `json:"time"` // ISO 8601 string } // LatencyTracker provides a generic structure for measuring time taken at various stages in message processing. // It can be embedded in message structs for tracking the flow of data and calculating round-trip latency. type LatencyTracker struct { - SequenceID string `json:"sequence_id"` - Timestamps []TimestampEntry `json:"timestamps"` + SequenceID string `json:"sequence_id"` + Timestamps []TimestampEntry `json:"timestamps"` + Metadata map[string]string `json:"metadata,omitempty"` } // NewLatencyTracker initializes a new LatencyTracker with the given sequence ID @@ -24,6 +23,7 @@ func NewLatencyTracker(sequenceID string) *LatencyTracker { return &LatencyTracker{ SequenceID: sequenceID, Timestamps: make([]TimestampEntry, 0), + Metadata: make(map[string]string), } } @@ -32,7 +32,7 @@ func (lt *LatencyTracker) AddTimestamp(stage string) { lt.Timestamps = append(lt.Timestamps, TimestampEntry{ Stage: stage, // Ensure extremely precise UTC RFC3339 timestamps (down to nanoseconds) - Time: time.Now().UTC(), + Time: time.Now().UTC().Format(time.RFC3339Nano), }) } @@ -44,11 +44,15 @@ func (lt *LatencyTracker) TotalLatency() (int64, error) { var earliest, latest time.Time for _, ts := range lt.Timestamps { - if earliest.IsZero() || ts.Time.Before(earliest) { - earliest = ts.Time + t, err := time.Parse(time.RFC3339, ts.Time) + if err != nil { + return 0, err } - if latest.IsZero() || ts.Time.After(latest) { - latest = ts.Time + if earliest.IsZero() || t.Before(earliest) { + earliest = t + } + if latest.IsZero() || t.After(latest) { + latest = t } } @@ -63,13 +67,14 @@ func (lt *LatencyTracker) PainPoints(threshold time.Duration) []string { for _, ts := range lt.Timestamps { stage := ts.Stage + t := ts.Time if lastStage == "" { lastStage = stage - lastTime = ts.Time + lastTime, _ = time.Parse(time.RFC3339, t) continue } - currentTime := ts.Time + currentTime, _ := time.Parse(time.RFC3339, t) if currentTime.Sub(lastTime) > threshold { painPoints = append(painPoints, fmt.Sprintf("%s -> %s", lastStage, stage)) } @@ -82,7 +87,7 @@ func (lt *LatencyTracker) PainPoints(threshold time.Duration) []string { // StageLatency calculates the time taken between two specific stages. func (lt *LatencyTracker) StageLatency(startStage, endStage string) (time.Duration, error) { - var startTime, endTime time.Time + startTime, endTime := "", "" for _, ts := range lt.Timestamps { if ts.Stage == startStage { startTime = ts.Time @@ -92,41 +97,18 @@ func (lt *LatencyTracker) StageLatency(startStage, endStage string) (time.Durati } } - /*if startTime == "" || endTime == "" { + if startTime == "" || endTime == "" { return 0, fmt.Errorf("missing timestamps for stages: %s -> %s", startStage, endStage) - }*/ + } - return endTime.Sub(startTime), nil -} - -func LatencyTrackerFromProto(protolt *gen.ProtoLatencyTracker) *LatencyTracker { - ret := &LatencyTracker{ - SequenceID: protolt.GetSequenceId(), - Timestamps: make([]TimestampEntry, 0), - } - - for _, ts := range protolt.GetTimestamps() { - ret.Timestamps = append(ret.Timestamps, TimestampEntry{ - Stage: ts.GetStage(), - Time: ts.GetTime().AsTime(), - }) - } - - return ret -} - -func (lt *LatencyTracker) ToProto() *gen.ProtoLatencyTracker { - ret := &gen.ProtoLatencyTracker{ - SequenceId: lt.SequenceID, - Timestamps: make([]*gen.ProtoTimestampEntry, len(lt.Timestamps)), - } - - for i, timestamp := range lt.Timestamps { - ret.Timestamps[i] = &gen.ProtoTimestampEntry{ - Stage: timestamp.Stage, - Time: timestamppb.New(timestamp.Time), - } - } - - return ret + start, err := time.Parse(time.RFC3339, startTime) + if err != nil { + return 0, err + } + end, err := time.Parse(time.RFC3339, endTime) + if err != nil { + return 0, err + } + + return end.Sub(start), nil } diff --git a/packages/relay/internal/messages.go b/packages/relay/internal/messages.go index 05ba5c44..2f102bd8 100644 --- a/packages/relay/internal/messages.go +++ b/packages/relay/internal/messages.go @@ -1,17 +1,27 @@ package relay import ( + "bytes" + "compress/gzip" + "encoding/json" + "fmt" "github.com/pion/webrtc/v4" "time" ) -// OnMessageCallback is a callback for messages of given type +// OnMessageCallback is a callback for binary messages of given type type OnMessageCallback func(data []byte) // MessageBase is the base type for WS/DC messages. type MessageBase struct { - PayloadType string `json:"payload_type"` - Latency *LatencyTracker `json:"latency,omitempty"` + PayloadType string `json:"payload_type"` + LatencyTracker LatencyTracker `json:"latency_tracker,omitempty"` +} + +// MessageInput represents an input message. +type MessageInput struct { + MessageBase + Data string `json:"data"` } // MessageLog represents a log message. @@ -83,6 +93,50 @@ type MessageAnswer struct { AnswerType AnswerType `json:"answer_type"` } +// EncodeMessage encodes a message to be sent with gzip compression +func EncodeMessage(msg interface{}) ([]byte, error) { + // Marshal the message to JSON + data, err := json.Marshal(msg) + if err != nil { + return nil, fmt.Errorf("failed to encode message: %w", err) + } + + // Gzip compress the JSON + var compressedData bytes.Buffer + writer := gzip.NewWriter(&compressedData) + _, err = writer.Write(data) + if err != nil { + return nil, fmt.Errorf("failed to compress message: %w", err) + } + if err := writer.Close(); err != nil { + return nil, fmt.Errorf("failed to finalize compression: %w", err) + } + + return compressedData.Bytes(), nil +} + +// DecodeMessage decodes a message received with gzip decompression +func DecodeMessage(data []byte, target interface{}) error { + // Gzip decompress the data + reader, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return fmt.Errorf("failed to initialize decompression: %w", err) + } + defer func(reader *gzip.Reader) { + if err = reader.Close(); err != nil { + fmt.Printf("failed to close reader: %v\n", err) + } + }(reader) + + // Decode the JSON + err = json.NewDecoder(reader).Decode(target) + if err != nil { + return fmt.Errorf("failed to decode message: %w", err) + } + + return nil +} + // SendLogMessageWS sends a log message to the given WebSocket connection. func (ws *SafeWebSocket) SendLogMessageWS(level, message string) error { msg := MessageLog{ @@ -91,7 +145,12 @@ func (ws *SafeWebSocket) SendLogMessageWS(level, message string) error { Message: message, Time: time.Now().Format(time.RFC3339), } - return ws.SendJSON(msg) + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode log message: %w", err) + } + + return ws.SendBinary(encoded) } // SendMetricsMessageWS sends a metrics message to the given WebSocket connection. @@ -103,7 +162,12 @@ func (ws *SafeWebSocket) SendMetricsMessageWS(usageCPU, usageMemory float64, upt Uptime: uptime, PipelineLatency: pipelineLatency, } - return ws.SendJSON(msg) + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode metrics message: %w", err) + } + + return ws.SendBinary(encoded) } // SendICECandidateMessageWS sends an ICE candidate message to the given WebSocket connection. @@ -112,7 +176,12 @@ func (ws *SafeWebSocket) SendICECandidateMessageWS(candidate webrtc.ICECandidate MessageBase: MessageBase{PayloadType: "ice"}, Candidate: candidate, } - return ws.SendJSON(msg) + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode ICE candidate message: %w", err) + } + + return ws.SendBinary(encoded) } // SendSDPMessageWS sends an SDP message to the given WebSocket connection. @@ -121,7 +190,12 @@ func (ws *SafeWebSocket) SendSDPMessageWS(sdp webrtc.SessionDescription) error { MessageBase: MessageBase{PayloadType: "sdp"}, SDP: sdp, } - return ws.SendJSON(msg) + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode SDP message: %w", err) + } + + return ws.SendBinary(encoded) } // SendAnswerMessageWS sends an answer message to the given WebSocket connection. @@ -130,5 +204,24 @@ func (ws *SafeWebSocket) SendAnswerMessageWS(answer AnswerType) error { MessageBase: MessageBase{PayloadType: "answer"}, AnswerType: answer, } - return ws.SendJSON(msg) + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode answer message: %w", err) + } + + return ws.SendBinary(encoded) +} + +// SendInputMessageDC sends an input message to the given DataChannel connection. +func (ndc *NestriDataChannel) SendInputMessageDC(data string) error { + msg := MessageInput{ + MessageBase: MessageBase{PayloadType: "input"}, + Data: data, + } + encoded, err := EncodeMessage(msg) + if err != nil { + return fmt.Errorf("failed to encode input message: %w", err) + } + + return ndc.SendBinary(encoded) } diff --git a/packages/relay/internal/proto/latency_tracker.pb.go b/packages/relay/internal/proto/latency_tracker.pb.go deleted file mode 100644 index a6bda859..00000000 --- a/packages/relay/internal/proto/latency_tracker.pb.go +++ /dev/null @@ -1,203 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.4 -// protoc (unknown) -// source: latency_tracker.proto - -package proto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ProtoTimestampEntry struct { - state protoimpl.MessageState `protogen:"open.v1"` - Stage string `protobuf:"bytes,1,opt,name=stage,proto3" json:"stage,omitempty"` - Time *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=time,proto3" json:"time,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoTimestampEntry) Reset() { - *x = ProtoTimestampEntry{} - mi := &file_latency_tracker_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoTimestampEntry) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoTimestampEntry) ProtoMessage() {} - -func (x *ProtoTimestampEntry) ProtoReflect() protoreflect.Message { - mi := &file_latency_tracker_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoTimestampEntry.ProtoReflect.Descriptor instead. -func (*ProtoTimestampEntry) Descriptor() ([]byte, []int) { - return file_latency_tracker_proto_rawDescGZIP(), []int{0} -} - -func (x *ProtoTimestampEntry) GetStage() string { - if x != nil { - return x.Stage - } - return "" -} - -func (x *ProtoTimestampEntry) GetTime() *timestamppb.Timestamp { - if x != nil { - return x.Time - } - return nil -} - -type ProtoLatencyTracker struct { - state protoimpl.MessageState `protogen:"open.v1"` - SequenceId string `protobuf:"bytes,1,opt,name=sequence_id,json=sequenceId,proto3" json:"sequence_id,omitempty"` - Timestamps []*ProtoTimestampEntry `protobuf:"bytes,2,rep,name=timestamps,proto3" json:"timestamps,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoLatencyTracker) Reset() { - *x = ProtoLatencyTracker{} - mi := &file_latency_tracker_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoLatencyTracker) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoLatencyTracker) ProtoMessage() {} - -func (x *ProtoLatencyTracker) ProtoReflect() protoreflect.Message { - mi := &file_latency_tracker_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoLatencyTracker.ProtoReflect.Descriptor instead. -func (*ProtoLatencyTracker) Descriptor() ([]byte, []int) { - return file_latency_tracker_proto_rawDescGZIP(), []int{1} -} - -func (x *ProtoLatencyTracker) GetSequenceId() string { - if x != nil { - return x.SequenceId - } - return "" -} - -func (x *ProtoLatencyTracker) GetTimestamps() []*ProtoTimestampEntry { - if x != nil { - return x.Timestamps - } - return nil -} - -var File_latency_tracker_proto protoreflect.FileDescriptor - -var file_latency_tracker_proto_rawDesc = string([]byte{ - 0x0a, 0x15, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, - 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0x5b, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x04, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x72, 0x0a, 0x13, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x72, 0x61, 0x63, - 0x6b, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, - 0x42, 0x16, 0x5a, 0x14, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -}) - -var ( - file_latency_tracker_proto_rawDescOnce sync.Once - file_latency_tracker_proto_rawDescData []byte -) - -func file_latency_tracker_proto_rawDescGZIP() []byte { - file_latency_tracker_proto_rawDescOnce.Do(func() { - file_latency_tracker_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_latency_tracker_proto_rawDesc), len(file_latency_tracker_proto_rawDesc))) - }) - return file_latency_tracker_proto_rawDescData -} - -var file_latency_tracker_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_latency_tracker_proto_goTypes = []any{ - (*ProtoTimestampEntry)(nil), // 0: proto.ProtoTimestampEntry - (*ProtoLatencyTracker)(nil), // 1: proto.ProtoLatencyTracker - (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp -} -var file_latency_tracker_proto_depIdxs = []int32{ - 2, // 0: proto.ProtoTimestampEntry.time:type_name -> google.protobuf.Timestamp - 0, // 1: proto.ProtoLatencyTracker.timestamps:type_name -> proto.ProtoTimestampEntry - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_latency_tracker_proto_init() } -func file_latency_tracker_proto_init() { - if File_latency_tracker_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_latency_tracker_proto_rawDesc), len(file_latency_tracker_proto_rawDesc)), - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_latency_tracker_proto_goTypes, - DependencyIndexes: file_latency_tracker_proto_depIdxs, - MessageInfos: file_latency_tracker_proto_msgTypes, - }.Build() - File_latency_tracker_proto = out.File - file_latency_tracker_proto_goTypes = nil - file_latency_tracker_proto_depIdxs = nil -} diff --git a/packages/relay/internal/proto/messages.pb.go b/packages/relay/internal/proto/messages.pb.go deleted file mode 100644 index 8faf7974..00000000 --- a/packages/relay/internal/proto/messages.pb.go +++ /dev/null @@ -1,207 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.4 -// protoc (unknown) -// source: messages.proto - -package proto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ProtoMessageBase struct { - state protoimpl.MessageState `protogen:"open.v1"` - PayloadType string `protobuf:"bytes,1,opt,name=payload_type,json=payloadType,proto3" json:"payload_type,omitempty"` - Latency *ProtoLatencyTracker `protobuf:"bytes,2,opt,name=latency,proto3" json:"latency,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMessageBase) Reset() { - *x = ProtoMessageBase{} - mi := &file_messages_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMessageBase) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMessageBase) ProtoMessage() {} - -func (x *ProtoMessageBase) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMessageBase.ProtoReflect.Descriptor instead. -func (*ProtoMessageBase) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{0} -} - -func (x *ProtoMessageBase) GetPayloadType() string { - if x != nil { - return x.PayloadType - } - return "" -} - -func (x *ProtoMessageBase) GetLatency() *ProtoLatencyTracker { - if x != nil { - return x.Latency - } - return nil -} - -type ProtoMessageInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - MessageBase *ProtoMessageBase `protobuf:"bytes,1,opt,name=message_base,json=messageBase,proto3" json:"message_base,omitempty"` - Data *ProtoInput `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMessageInput) Reset() { - *x = ProtoMessageInput{} - mi := &file_messages_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMessageInput) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMessageInput) ProtoMessage() {} - -func (x *ProtoMessageInput) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMessageInput.ProtoReflect.Descriptor instead. -func (*ProtoMessageInput) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{1} -} - -func (x *ProtoMessageInput) GetMessageBase() *ProtoMessageBase { - if x != nil { - return x.MessageBase - } - return nil -} - -func (x *ProtoMessageInput) GetData() *ProtoInput { - if x != nil { - return x.Data - } - return nil -} - -var File_messages_proto protoreflect.FileDescriptor - -var file_messages_proto_rawDesc = string([]byte{ - 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x74, 0x72, - 0x61, 0x63, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6b, 0x0a, 0x10, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x72, 0x52, - 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x76, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x3a, 0x0a, - 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x52, 0x0b, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x61, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x42, 0x16, 0x5a, 0x14, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -}) - -var ( - file_messages_proto_rawDescOnce sync.Once - file_messages_proto_rawDescData []byte -) - -func file_messages_proto_rawDescGZIP() []byte { - file_messages_proto_rawDescOnce.Do(func() { - file_messages_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc))) - }) - return file_messages_proto_rawDescData -} - -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_messages_proto_goTypes = []any{ - (*ProtoMessageBase)(nil), // 0: proto.ProtoMessageBase - (*ProtoMessageInput)(nil), // 1: proto.ProtoMessageInput - (*ProtoLatencyTracker)(nil), // 2: proto.ProtoLatencyTracker - (*ProtoInput)(nil), // 3: proto.ProtoInput -} -var file_messages_proto_depIdxs = []int32{ - 2, // 0: proto.ProtoMessageBase.latency:type_name -> proto.ProtoLatencyTracker - 0, // 1: proto.ProtoMessageInput.message_base:type_name -> proto.ProtoMessageBase - 3, // 2: proto.ProtoMessageInput.data:type_name -> proto.ProtoInput - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_messages_proto_init() } -func file_messages_proto_init() { - if File_messages_proto != nil { - return - } - file_types_proto_init() - file_latency_tracker_proto_init() - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)), - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_messages_proto_goTypes, - DependencyIndexes: file_messages_proto_depIdxs, - MessageInfos: file_messages_proto_msgTypes, - }.Build() - File_messages_proto = out.File - file_messages_proto_goTypes = nil - file_messages_proto_depIdxs = nil -} diff --git a/packages/relay/internal/proto/types.pb.go b/packages/relay/internal/proto/types.pb.go deleted file mode 100644 index ab989112..00000000 --- a/packages/relay/internal/proto/types.pb.go +++ /dev/null @@ -1,713 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.4 -// protoc (unknown) -// source: types.proto - -package proto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// MouseMove message -type ProtoMouseMove struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "MouseMove" - X int32 `protobuf:"varint,2,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,3,opt,name=y,proto3" json:"y,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMouseMove) Reset() { - *x = ProtoMouseMove{} - mi := &file_types_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMouseMove) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMouseMove) ProtoMessage() {} - -func (x *ProtoMouseMove) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMouseMove.ProtoReflect.Descriptor instead. -func (*ProtoMouseMove) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{0} -} - -func (x *ProtoMouseMove) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoMouseMove) GetX() int32 { - if x != nil { - return x.X - } - return 0 -} - -func (x *ProtoMouseMove) GetY() int32 { - if x != nil { - return x.Y - } - return 0 -} - -// MouseMoveAbs message -type ProtoMouseMoveAbs struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "MouseMoveAbs" - X int32 `protobuf:"varint,2,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,3,opt,name=y,proto3" json:"y,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMouseMoveAbs) Reset() { - *x = ProtoMouseMoveAbs{} - mi := &file_types_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMouseMoveAbs) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMouseMoveAbs) ProtoMessage() {} - -func (x *ProtoMouseMoveAbs) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMouseMoveAbs.ProtoReflect.Descriptor instead. -func (*ProtoMouseMoveAbs) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{1} -} - -func (x *ProtoMouseMoveAbs) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoMouseMoveAbs) GetX() int32 { - if x != nil { - return x.X - } - return 0 -} - -func (x *ProtoMouseMoveAbs) GetY() int32 { - if x != nil { - return x.Y - } - return 0 -} - -// MouseWheel message -type ProtoMouseWheel struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "MouseWheel" - X int32 `protobuf:"varint,2,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,3,opt,name=y,proto3" json:"y,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMouseWheel) Reset() { - *x = ProtoMouseWheel{} - mi := &file_types_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMouseWheel) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMouseWheel) ProtoMessage() {} - -func (x *ProtoMouseWheel) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMouseWheel.ProtoReflect.Descriptor instead. -func (*ProtoMouseWheel) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{2} -} - -func (x *ProtoMouseWheel) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoMouseWheel) GetX() int32 { - if x != nil { - return x.X - } - return 0 -} - -func (x *ProtoMouseWheel) GetY() int32 { - if x != nil { - return x.Y - } - return 0 -} - -// MouseKeyDown message -type ProtoMouseKeyDown struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "MouseKeyDown" - Key int32 `protobuf:"varint,2,opt,name=key,proto3" json:"key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMouseKeyDown) Reset() { - *x = ProtoMouseKeyDown{} - mi := &file_types_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMouseKeyDown) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMouseKeyDown) ProtoMessage() {} - -func (x *ProtoMouseKeyDown) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMouseKeyDown.ProtoReflect.Descriptor instead. -func (*ProtoMouseKeyDown) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{3} -} - -func (x *ProtoMouseKeyDown) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoMouseKeyDown) GetKey() int32 { - if x != nil { - return x.Key - } - return 0 -} - -// MouseKeyUp message -type ProtoMouseKeyUp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "MouseKeyUp" - Key int32 `protobuf:"varint,2,opt,name=key,proto3" json:"key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoMouseKeyUp) Reset() { - *x = ProtoMouseKeyUp{} - mi := &file_types_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoMouseKeyUp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoMouseKeyUp) ProtoMessage() {} - -func (x *ProtoMouseKeyUp) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoMouseKeyUp.ProtoReflect.Descriptor instead. -func (*ProtoMouseKeyUp) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{4} -} - -func (x *ProtoMouseKeyUp) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoMouseKeyUp) GetKey() int32 { - if x != nil { - return x.Key - } - return 0 -} - -// KeyDown message -type ProtoKeyDown struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "KeyDown" - Key int32 `protobuf:"varint,2,opt,name=key,proto3" json:"key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoKeyDown) Reset() { - *x = ProtoKeyDown{} - mi := &file_types_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoKeyDown) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoKeyDown) ProtoMessage() {} - -func (x *ProtoKeyDown) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoKeyDown.ProtoReflect.Descriptor instead. -func (*ProtoKeyDown) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{5} -} - -func (x *ProtoKeyDown) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoKeyDown) GetKey() int32 { - if x != nil { - return x.Key - } - return 0 -} - -// KeyUp message -type ProtoKeyUp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Fixed value "KeyUp" - Key int32 `protobuf:"varint,2,opt,name=key,proto3" json:"key,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoKeyUp) Reset() { - *x = ProtoKeyUp{} - mi := &file_types_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoKeyUp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoKeyUp) ProtoMessage() {} - -func (x *ProtoKeyUp) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[6] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoKeyUp.ProtoReflect.Descriptor instead. -func (*ProtoKeyUp) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{6} -} - -func (x *ProtoKeyUp) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ProtoKeyUp) GetKey() int32 { - if x != nil { - return x.Key - } - return 0 -} - -// Union of all Input types -type ProtoInput struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to InputType: - // - // *ProtoInput_MouseMove - // *ProtoInput_MouseMoveAbs - // *ProtoInput_MouseWheel - // *ProtoInput_MouseKeyDown - // *ProtoInput_MouseKeyUp - // *ProtoInput_KeyDown - // *ProtoInput_KeyUp - InputType isProtoInput_InputType `protobuf_oneof:"input_type"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ProtoInput) Reset() { - *x = ProtoInput{} - mi := &file_types_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ProtoInput) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProtoInput) ProtoMessage() {} - -func (x *ProtoInput) ProtoReflect() protoreflect.Message { - mi := &file_types_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProtoInput.ProtoReflect.Descriptor instead. -func (*ProtoInput) Descriptor() ([]byte, []int) { - return file_types_proto_rawDescGZIP(), []int{7} -} - -func (x *ProtoInput) GetInputType() isProtoInput_InputType { - if x != nil { - return x.InputType - } - return nil -} - -func (x *ProtoInput) GetMouseMove() *ProtoMouseMove { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_MouseMove); ok { - return x.MouseMove - } - } - return nil -} - -func (x *ProtoInput) GetMouseMoveAbs() *ProtoMouseMoveAbs { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_MouseMoveAbs); ok { - return x.MouseMoveAbs - } - } - return nil -} - -func (x *ProtoInput) GetMouseWheel() *ProtoMouseWheel { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_MouseWheel); ok { - return x.MouseWheel - } - } - return nil -} - -func (x *ProtoInput) GetMouseKeyDown() *ProtoMouseKeyDown { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_MouseKeyDown); ok { - return x.MouseKeyDown - } - } - return nil -} - -func (x *ProtoInput) GetMouseKeyUp() *ProtoMouseKeyUp { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_MouseKeyUp); ok { - return x.MouseKeyUp - } - } - return nil -} - -func (x *ProtoInput) GetKeyDown() *ProtoKeyDown { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_KeyDown); ok { - return x.KeyDown - } - } - return nil -} - -func (x *ProtoInput) GetKeyUp() *ProtoKeyUp { - if x != nil { - if x, ok := x.InputType.(*ProtoInput_KeyUp); ok { - return x.KeyUp - } - } - return nil -} - -type isProtoInput_InputType interface { - isProtoInput_InputType() -} - -type ProtoInput_MouseMove struct { - MouseMove *ProtoMouseMove `protobuf:"bytes,1,opt,name=mouse_move,json=mouseMove,proto3,oneof"` -} - -type ProtoInput_MouseMoveAbs struct { - MouseMoveAbs *ProtoMouseMoveAbs `protobuf:"bytes,2,opt,name=mouse_move_abs,json=mouseMoveAbs,proto3,oneof"` -} - -type ProtoInput_MouseWheel struct { - MouseWheel *ProtoMouseWheel `protobuf:"bytes,3,opt,name=mouse_wheel,json=mouseWheel,proto3,oneof"` -} - -type ProtoInput_MouseKeyDown struct { - MouseKeyDown *ProtoMouseKeyDown `protobuf:"bytes,4,opt,name=mouse_key_down,json=mouseKeyDown,proto3,oneof"` -} - -type ProtoInput_MouseKeyUp struct { - MouseKeyUp *ProtoMouseKeyUp `protobuf:"bytes,5,opt,name=mouse_key_up,json=mouseKeyUp,proto3,oneof"` -} - -type ProtoInput_KeyDown struct { - KeyDown *ProtoKeyDown `protobuf:"bytes,6,opt,name=key_down,json=keyDown,proto3,oneof"` -} - -type ProtoInput_KeyUp struct { - KeyUp *ProtoKeyUp `protobuf:"bytes,7,opt,name=key_up,json=keyUp,proto3,oneof"` -} - -func (*ProtoInput_MouseMove) isProtoInput_InputType() {} - -func (*ProtoInput_MouseMoveAbs) isProtoInput_InputType() {} - -func (*ProtoInput_MouseWheel) isProtoInput_InputType() {} - -func (*ProtoInput_MouseKeyDown) isProtoInput_InputType() {} - -func (*ProtoInput_MouseKeyUp) isProtoInput_InputType() {} - -func (*ProtoInput_KeyDown) isProtoInput_InputType() {} - -func (*ProtoInput_KeyUp) isProtoInput_InputType() {} - -var File_types_proto protoreflect.FileDescriptor - -var file_types_proto_rawDesc = string([]byte{ - 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x40, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, - 0x73, 0x65, 0x4d, 0x6f, 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0x43, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, - 0x6f, 0x75, 0x73, 0x65, 0x4d, 0x6f, 0x76, 0x65, 0x41, 0x62, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, - 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0x41, 0x0a, 0x0f, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x57, 0x68, 0x65, 0x65, 0x6c, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, - 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0x39, - 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x44, - 0x6f, 0x77, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x37, 0x0a, 0x0f, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x55, 0x70, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0x34, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, 0x79, 0x44, 0x6f, - 0x77, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x32, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x4b, 0x65, 0x79, 0x55, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xab, 0x03, 0x0a, - 0x0a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x6d, - 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, - 0x73, 0x65, 0x4d, 0x6f, 0x76, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x4d, - 0x6f, 0x76, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x6f, 0x76, - 0x65, 0x5f, 0x61, 0x62, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x4d, 0x6f, - 0x76, 0x65, 0x41, 0x62, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x4d, 0x6f, - 0x76, 0x65, 0x41, 0x62, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x77, - 0x68, 0x65, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x57, 0x68, 0x65, - 0x65, 0x6c, 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x57, 0x68, 0x65, 0x65, 0x6c, - 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x6f, - 0x77, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x44, 0x6f, - 0x77, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x44, 0x6f, - 0x77, 0x6e, 0x12, 0x3a, 0x0a, 0x0c, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x55, 0x70, - 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x55, 0x70, 0x12, 0x30, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, - 0x79, 0x44, 0x6f, 0x77, 0x6e, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x6f, 0x77, 0x6e, - 0x12, 0x2a, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x4b, 0x65, - 0x79, 0x55, 0x70, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x55, 0x70, 0x42, 0x0c, 0x0a, 0x0a, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x42, 0x16, 0x5a, 0x14, 0x72, 0x65, - 0x6c, 0x61, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -}) - -var ( - file_types_proto_rawDescOnce sync.Once - file_types_proto_rawDescData []byte -) - -func file_types_proto_rawDescGZIP() []byte { - file_types_proto_rawDescOnce.Do(func() { - file_types_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_types_proto_rawDesc), len(file_types_proto_rawDesc))) - }) - return file_types_proto_rawDescData -} - -var file_types_proto_msgTypes = make([]protoimpl.MessageInfo, 8) -var file_types_proto_goTypes = []any{ - (*ProtoMouseMove)(nil), // 0: proto.ProtoMouseMove - (*ProtoMouseMoveAbs)(nil), // 1: proto.ProtoMouseMoveAbs - (*ProtoMouseWheel)(nil), // 2: proto.ProtoMouseWheel - (*ProtoMouseKeyDown)(nil), // 3: proto.ProtoMouseKeyDown - (*ProtoMouseKeyUp)(nil), // 4: proto.ProtoMouseKeyUp - (*ProtoKeyDown)(nil), // 5: proto.ProtoKeyDown - (*ProtoKeyUp)(nil), // 6: proto.ProtoKeyUp - (*ProtoInput)(nil), // 7: proto.ProtoInput -} -var file_types_proto_depIdxs = []int32{ - 0, // 0: proto.ProtoInput.mouse_move:type_name -> proto.ProtoMouseMove - 1, // 1: proto.ProtoInput.mouse_move_abs:type_name -> proto.ProtoMouseMoveAbs - 2, // 2: proto.ProtoInput.mouse_wheel:type_name -> proto.ProtoMouseWheel - 3, // 3: proto.ProtoInput.mouse_key_down:type_name -> proto.ProtoMouseKeyDown - 4, // 4: proto.ProtoInput.mouse_key_up:type_name -> proto.ProtoMouseKeyUp - 5, // 5: proto.ProtoInput.key_down:type_name -> proto.ProtoKeyDown - 6, // 6: proto.ProtoInput.key_up:type_name -> proto.ProtoKeyUp - 7, // [7:7] is the sub-list for method output_type - 7, // [7:7] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name -} - -func init() { file_types_proto_init() } -func file_types_proto_init() { - if File_types_proto != nil { - return - } - file_types_proto_msgTypes[7].OneofWrappers = []any{ - (*ProtoInput_MouseMove)(nil), - (*ProtoInput_MouseMoveAbs)(nil), - (*ProtoInput_MouseWheel)(nil), - (*ProtoInput_MouseKeyDown)(nil), - (*ProtoInput_MouseKeyUp)(nil), - (*ProtoInput_KeyDown)(nil), - (*ProtoInput_KeyUp)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_types_proto_rawDesc), len(file_types_proto_rawDesc)), - NumEnums: 0, - NumMessages: 8, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_types_proto_goTypes, - DependencyIndexes: file_types_proto_depIdxs, - MessageInfos: file_types_proto_msgTypes, - }.Build() - File_types_proto = out.File - file_types_proto_goTypes = nil - file_types_proto_depIdxs = nil -} diff --git a/packages/relay/internal/websocket.go b/packages/relay/internal/websocket.go index 2c85fdbc..9b8f3bd9 100644 --- a/packages/relay/internal/websocket.go +++ b/packages/relay/internal/websocket.go @@ -1,7 +1,6 @@ package relay import ( - "encoding/json" "github.com/gorilla/websocket" "log" "sync" @@ -11,22 +10,22 @@ import ( type SafeWebSocket struct { *websocket.Conn sync.Mutex - closeCallback func() // OnClose callback - callbacks map[string]OnMessageCallback // MessageBase type -> callback + closeCallback func() // OnClose callback + binaryCallbacks map[string]OnMessageCallback // MessageBase type -> callback } // NewSafeWebSocket creates a new SafeWebSocket from *websocket.Conn func NewSafeWebSocket(conn *websocket.Conn) *SafeWebSocket { ws := &SafeWebSocket{ - Conn: conn, - closeCallback: nil, - callbacks: make(map[string]OnMessageCallback), + Conn: conn, + closeCallback: nil, + binaryCallbacks: make(map[string]OnMessageCallback), } - // Launch a goroutine to handle messages + // Launch a goroutine to handle binary messages go func() { for { - // Read message + // Read binary message kind, data, err := ws.Conn.ReadMessage() if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure, websocket.CloseNoStatusReceived) { // If unexpected close error, break @@ -43,23 +42,22 @@ func NewSafeWebSocket(conn *websocket.Conn) *SafeWebSocket { switch kind { case websocket.TextMessage: + // Ignore, we use binary messages + continue + case websocket.BinaryMessage: // Decode message var msg MessageBase - if err = json.Unmarshal(data, &msg); err != nil { - log.Printf("Failed to decode text WebSocket message, reason: %s\n", err) + if err = DecodeMessage(data, &msg); err != nil { + log.Printf("Failed to decode binary WebSocket message, reason: %s\n", err) continue } // Handle message type callback - if callback, ok := ws.callbacks[msg.PayloadType]; ok { + if callback, ok := ws.binaryCallbacks[msg.PayloadType]; ok { callback(data) } // TODO: Log unknown message type? - break - case websocket.BinaryMessage: - break default: log.Printf("Unknown WebSocket message type: %d\n", kind) - break } } @@ -90,18 +88,18 @@ func (ws *SafeWebSocket) SendBinary(data []byte) error { func (ws *SafeWebSocket) RegisterMessageCallback(msgType string, callback OnMessageCallback) { ws.Lock() defer ws.Unlock() - if ws.callbacks == nil { - ws.callbacks = make(map[string]OnMessageCallback) + if ws.binaryCallbacks == nil { + ws.binaryCallbacks = make(map[string]OnMessageCallback) } - ws.callbacks[msgType] = callback + ws.binaryCallbacks[msgType] = callback } // UnregisterMessageCallback removes the callback for binary message of given type func (ws *SafeWebSocket) UnregisterMessageCallback(msgType string) { ws.Lock() defer ws.Unlock() - if ws.callbacks != nil { - delete(ws.callbacks, msgType) + if ws.binaryCallbacks != nil { + delete(ws.binaryCallbacks, msgType) } } @@ -110,7 +108,7 @@ func (ws *SafeWebSocket) RegisterOnClose(callback func()) { ws.closeCallback = func() { // Clear our callbacks ws.Lock() - ws.callbacks = nil + ws.binaryCallbacks = nil ws.Unlock() // Call the callback callback() diff --git a/packages/server/Cargo.toml b/packages/server/Cargo.toml index d2eec91a..fc65ba2e 100644 --- a/packages/server/Cargo.toml +++ b/packages/server/Cargo.toml @@ -15,15 +15,15 @@ serde = {version = "1.0.214", features = ["derive"] } tokio = { version = "1.41.0", features = ["full"] } clap = { version = "4.5.20", features = ["env"] } serde_json = "1.0.132" -webrtc = "0.12.0" +webrtc = "0.11.0" regex = "1.11.1" -rand = "0.9.0" +rand = "0.8.5" rustls = { version = "0.23.17", features = ["ring"] } -tokio-tungstenite = { version = "0.26.1", features = ["native-tls"] } +tokio-util = "0.7.12" +flate2 = "1.0.35" +tokio-tungstenite = { version = "0.24.0", features = ["native-tls"] } log = { version = "0.4.22", features = ["std"] } chrono = "0.4.38" futures-util = "0.3.31" num-derive = "0.4.2" num-traits = "0.2.19" -prost = "0.13.4" -prost-types = "0.13.4" diff --git a/packages/server/src/args/app_args.rs b/packages/server/src/args/app_args.rs index 3d94c7e8..ef937f90 100644 --- a/packages/server/src/args/app_args.rs +++ b/packages/server/src/args/app_args.rs @@ -48,10 +48,7 @@ impl AppArgs { .unwrap() .parse::() .unwrap_or(60), - relay_url: matches - .get_one::("relay-url") - .expect("relay url cannot be empty") - .clone(), + relay_url: matches.get_one::("relay-url").unwrap().clone(), // Generate random room name if not provided room: matches .get_one::("room") diff --git a/packages/server/src/latency.rs b/packages/server/src/latency.rs index 8e3f3340..659c35d0 100644 --- a/packages/server/src/latency.rs +++ b/packages/server/src/latency.rs @@ -1,5 +1,5 @@ -use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug)] pub struct TimestampEntry { diff --git a/packages/server/src/main.rs b/packages/server/src/main.rs index cf32ecaa..99c32860 100644 --- a/packages/server/src/main.rs +++ b/packages/server/src/main.rs @@ -5,7 +5,6 @@ mod latency; mod messages; mod nestrisink; mod websocket; -mod proto; use crate::args::encoding_args; use crate::nestrisink::NestriSignaller; diff --git a/packages/server/src/messages.rs b/packages/server/src/messages.rs index e1550f8d..4cd8d346 100644 --- a/packages/server/src/messages.rs +++ b/packages/server/src/messages.rs @@ -1,14 +1,50 @@ -use crate::latency::LatencyTracker; +use std::error::Error; +use std::io::{Read, Write}; +use flate2::Compression; +use flate2::read::GzDecoder; +use flate2::write::GzEncoder; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; use serde::{Deserialize, Serialize}; -use std::error::Error; use webrtc::ice_transport::ice_candidate::RTCIceCandidateInit; use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; +use crate::latency::LatencyTracker; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +pub enum InputMessage { + #[serde(rename = "mousemove")] + MouseMove { x: i32, y: i32 }, + + #[serde(rename = "mousemoveabs")] + MouseMoveAbs { x: i32, y: i32 }, + + #[serde(rename = "wheel")] + Wheel { x: f64, y: f64 }, + + #[serde(rename = "mousedown")] + MouseDown { key: i32 }, + // Add other variants as needed + #[serde(rename = "mouseup")] + MouseUp { key: i32 }, + + #[serde(rename = "keydown")] + KeyDown { key: i32 }, + + #[serde(rename = "keyup")] + KeyUp { key: i32 }, +} #[derive(Serialize, Deserialize, Debug)] pub struct MessageBase { pub payload_type: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct MessageInput { + #[serde(flatten)] + pub base: MessageBase, + pub data: String, pub latency: Option, } @@ -100,21 +136,34 @@ pub struct MessageAnswer { pub answer_type: AnswerType, } -pub fn encode_message(message: &T) -> Result> { +pub fn encode_message(message: &T) -> Result, Box> { // Serialize the message to JSON let json = serde_json::to_string(message)?; - Ok(json) + + // Compress the JSON using gzip + let mut encoder = GzEncoder::new(Vec::new(), Compression::default()); + encoder.write_all(json.as_bytes())?; + let compressed_data = encoder.finish()?; + + Ok(compressed_data) } -pub fn decode_message(data: String) -> Result> { - println!("Data: {}", data); - let base_message: MessageBase = serde_json::from_str(&data)?; +pub fn decode_message(data: &[u8]) -> Result> { + let mut decoder = GzDecoder::new(data); + let mut decompressed_data = String::new(); + decoder.read_to_string(&mut decompressed_data)?; + + let base_message: MessageBase = serde_json::from_str(&decompressed_data)?; Ok(base_message) } pub fn decode_message_as Deserialize<'de>>( - data: String, + data: Vec, ) -> Result> { - let message: T = serde_json::from_str(&data)?; + let mut decoder = GzDecoder::new(data.as_slice()); + let mut decompressed_data = String::new(); + decoder.read_to_string(&mut decompressed_data)?; + + let message: T = serde_json::from_str(&decompressed_data)?; Ok(message) -} +} \ No newline at end of file diff --git a/packages/server/src/nestrisink/imp.rs b/packages/server/src/nestrisink/imp.rs index 71a195e9..4df2e499 100644 --- a/packages/server/src/nestrisink/imp.rs +++ b/packages/server/src/nestrisink/imp.rs @@ -1,18 +1,13 @@ use crate::messages::{ - decode_message_as, encode_message, AnswerType, JoinerType, MessageAnswer, MessageBase, - MessageICE, MessageJoin, MessageSDP, + decode_message_as, encode_message, AnswerType, InputMessage, JoinerType, MessageAnswer, + MessageBase, MessageICE, MessageInput, MessageJoin, MessageSDP, }; -use crate::proto::proto::proto_input::InputType::{ - KeyDown, KeyUp, MouseKeyDown, MouseKeyUp, MouseMove, MouseMoveAbs, MouseWheel, -}; -use crate::proto::proto::{ProtoInput, ProtoMessageInput}; use crate::websocket::NestriWebSocket; use glib::subclass::prelude::*; use gst::glib; use gst::prelude::*; use gst_webrtc::{gst_sdp, WebRTCSDPType, WebRTCSessionDescription}; use gstrswebrtc::signaller::{Signallable, SignallableImpl}; -use prost::Message; use std::collections::HashSet; use std::sync::{Arc, LazyLock}; use std::sync::{Mutex, RwLock}; @@ -205,7 +200,6 @@ impl SignallableImpl for Signaller { let join_msg = MessageJoin { base: MessageBase { payload_type: "join".to_string(), - latency: None, }, joiner_type: JoinerType::JoinerNode, }; @@ -243,7 +237,6 @@ impl SignallableImpl for Signaller { let join_msg = MessageJoin { base: MessageBase { payload_type: "join".to_string(), - latency: None, }, joiner_type: JoinerType::JoinerNode, }; @@ -272,7 +265,6 @@ impl SignallableImpl for Signaller { let sdp_message = MessageSDP { base: MessageBase { payload_type: "sdp".to_string(), - latency: None, }, sdp: RTCSessionDescription::offer(sdp.sdp().as_text().unwrap()).unwrap(), }; @@ -309,7 +301,6 @@ impl SignallableImpl for Signaller { let ice_message = MessageICE { base: MessageBase { payload_type: "ice".to_string(), - latency: None, }, candidate: candidate_init, }; @@ -363,9 +354,11 @@ fn setup_data_channel(data_channel: &gst_webrtc::WebRTCDataChannel, pipeline: &g data_channel.connect_on_message_data(move |_data_channel, data| { if let Some(data) = data { - match ProtoMessageInput::decode(data.to_vec().as_slice()) { + match decode_message_as::(data.to_vec()) { Ok(message_input) => { - if let Some(input_msg) = message_input.data { + // Deserialize the input message data + if let Ok(input_msg) = serde_json::from_str::(&message_input.data) + { // Process the input message and create an event if let Some(event) = handle_input_message(input_msg, &pressed_keys, &pressed_buttons) @@ -386,92 +379,88 @@ fn setup_data_channel(data_channel: &gst_webrtc::WebRTCDataChannel, pipeline: &g } fn handle_input_message( - input_msg: ProtoInput, + input_msg: InputMessage, pressed_keys: &Arc>>, pressed_buttons: &Arc>>, ) -> Option { - if let Some(input_type) = input_msg.input_type { - match input_type { - MouseMove(data) => { - let structure = gst::Structure::builder("MouseMoveRelative") - .field("pointer_x", data.x as f64) - .field("pointer_y", data.y as f64) - .build(); + match input_msg { + InputMessage::MouseMove { x, y } => { + let structure = gst::Structure::builder("MouseMoveRelative") + .field("pointer_x", x as f64) + .field("pointer_y", y as f64) + .build(); - Some(gst::event::CustomUpstream::new(structure)) - } - MouseMoveAbs(data) => { - let structure = gst::Structure::builder("MouseMoveAbsolute") - .field("pointer_x", data.x as f64) - .field("pointer_y", data.y as f64) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } - KeyDown(data) => { - let mut keys = pressed_keys.lock().unwrap(); - // If the key is already pressed, return to prevent key lockup - if keys.contains(&data.key) { - return None; - } - keys.insert(data.key); - - let structure = gst::Structure::builder("KeyboardKey") - .field("key", data.key as u32) - .field("pressed", true) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } - KeyUp(data) => { - let mut keys = pressed_keys.lock().unwrap(); - // Remove the key from the pressed state when released - keys.remove(&data.key); - - let structure = gst::Structure::builder("KeyboardKey") - .field("key", data.key as u32) - .field("pressed", false) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } - MouseWheel(data) => { - let structure = gst::Structure::builder("MouseAxis") - .field("x", data.x as f64) - .field("y", data.y as f64) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } - MouseKeyDown(data) => { - let mut buttons = pressed_buttons.lock().unwrap(); - // If the button is already pressed, return to prevent button lockup - if buttons.contains(&data.key) { - return None; - } - buttons.insert(data.key); - - let structure = gst::Structure::builder("MouseButton") - .field("button", data.key as u32) - .field("pressed", true) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } - MouseKeyUp(data) => { - let mut buttons = pressed_buttons.lock().unwrap(); - // Remove the button from the pressed state when released - buttons.remove(&data.key); - - let structure = gst::Structure::builder("MouseButton") - .field("button", data.key as u32) - .field("pressed", false) - .build(); - - Some(gst::event::CustomUpstream::new(structure)) - } + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::MouseMoveAbs { x, y } => { + let structure = gst::Structure::builder("MouseMoveAbsolute") + .field("pointer_x", x as f64) + .field("pointer_y", y as f64) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::KeyDown { key } => { + let mut keys = pressed_keys.lock().unwrap(); + // If the key is already pressed, return to prevent key lockup + if keys.contains(&key) { + return None; + } + keys.insert(key); + + let structure = gst::Structure::builder("KeyboardKey") + .field("key", key as u32) + .field("pressed", true) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::KeyUp { key } => { + let mut keys = pressed_keys.lock().unwrap(); + // Remove the key from the pressed state when released + keys.remove(&key); + + let structure = gst::Structure::builder("KeyboardKey") + .field("key", key as u32) + .field("pressed", false) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::Wheel { x, y } => { + let structure = gst::Structure::builder("MouseAxis") + .field("x", x as f64) + .field("y", y as f64) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::MouseDown { key } => { + let mut buttons = pressed_buttons.lock().unwrap(); + // If the button is already pressed, return to prevent button lockup + if buttons.contains(&key) { + return None; + } + buttons.insert(key); + + let structure = gst::Structure::builder("MouseButton") + .field("button", key as u32) + .field("pressed", true) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) + } + InputMessage::MouseUp { key } => { + let mut buttons = pressed_buttons.lock().unwrap(); + // Remove the button from the pressed state when released + buttons.remove(&key); + + let structure = gst::Structure::builder("MouseButton") + .field("button", key as u32) + .field("pressed", false) + .build(); + + Some(gst::event::CustomUpstream::new(structure)) } - } else { - None } } diff --git a/packages/server/src/proto.rs b/packages/server/src/proto.rs deleted file mode 100644 index 3e1772e2..00000000 --- a/packages/server/src/proto.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod proto; \ No newline at end of file diff --git a/packages/server/src/proto/proto.rs b/packages/server/src/proto/proto.rs deleted file mode 100644 index 3c1e3d56..00000000 --- a/packages/server/src/proto/proto.rs +++ /dev/null @@ -1,139 +0,0 @@ -// @generated -// This file is @generated by prost-build. -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoTimestampEntry { - #[prost(string, tag="1")] - pub stage: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub time: ::core::option::Option<::prost_types::Timestamp>, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoLatencyTracker { - #[prost(string, tag="1")] - pub sequence_id: ::prost::alloc::string::String, - #[prost(message, repeated, tag="2")] - pub timestamps: ::prost::alloc::vec::Vec, -} -/// MouseMove message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMouseMove { - /// Fixed value "MouseMove" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub x: i32, - #[prost(int32, tag="3")] - pub y: i32, -} -/// MouseMoveAbs message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMouseMoveAbs { - /// Fixed value "MouseMoveAbs" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub x: i32, - #[prost(int32, tag="3")] - pub y: i32, -} -/// MouseWheel message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMouseWheel { - /// Fixed value "MouseWheel" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub x: i32, - #[prost(int32, tag="3")] - pub y: i32, -} -/// MouseKeyDown message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMouseKeyDown { - /// Fixed value "MouseKeyDown" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub key: i32, -} -/// MouseKeyUp message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMouseKeyUp { - /// Fixed value "MouseKeyUp" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub key: i32, -} -/// KeyDown message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoKeyDown { - /// Fixed value "KeyDown" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub key: i32, -} -/// KeyUp message -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoKeyUp { - /// Fixed value "KeyUp" - #[prost(string, tag="1")] - pub r#type: ::prost::alloc::string::String, - #[prost(int32, tag="2")] - pub key: i32, -} -/// Union of all Input types -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoInput { - #[prost(oneof="proto_input::InputType", tags="1, 2, 3, 4, 5, 6, 7")] - pub input_type: ::core::option::Option, -} -/// Nested message and enum types in `ProtoInput`. -pub mod proto_input { - #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] - pub enum InputType { - #[prost(message, tag="1")] - MouseMove(super::ProtoMouseMove), - #[prost(message, tag="2")] - MouseMoveAbs(super::ProtoMouseMoveAbs), - #[prost(message, tag="3")] - MouseWheel(super::ProtoMouseWheel), - #[prost(message, tag="4")] - MouseKeyDown(super::ProtoMouseKeyDown), - #[prost(message, tag="5")] - MouseKeyUp(super::ProtoMouseKeyUp), - #[prost(message, tag="6")] - KeyDown(super::ProtoKeyDown), - #[prost(message, tag="7")] - KeyUp(super::ProtoKeyUp), - } -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMessageBase { - #[prost(string, tag="1")] - pub payload_type: ::prost::alloc::string::String, - #[prost(message, optional, tag="2")] - pub latency: ::core::option::Option, -} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ProtoMessageInput { - #[prost(message, optional, tag="1")] - pub message_base: ::core::option::Option, - #[prost(message, optional, tag="2")] - pub data: ::core::option::Option, -} -// @@protoc_insertion_point(module) diff --git a/packages/server/src/websocket.rs b/packages/server/src/websocket.rs index e98d47a4..b850aaab 100644 --- a/packages/server/src/websocket.rs +++ b/packages/server/src/websocket.rs @@ -10,10 +10,10 @@ use std::time::Duration; use tokio::net::TcpStream; use tokio::sync::{mpsc, Mutex, Notify}; use tokio::time::sleep; -use tokio_tungstenite::tungstenite::{Message, Utf8Bytes}; +use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; -type Callback = Box; +type Callback = Box) + Send + Sync>; type WSRead = SplitStream>>; type WSWrite = SplitSink>, Message>; @@ -23,7 +23,7 @@ pub struct NestriWebSocket { reader: Arc>>, writer: Arc>>, callbacks: Arc>>, - message_tx: mpsc::UnboundedSender, + message_tx: mpsc::UnboundedSender>, reconnected_notify: Arc, } impl NestriWebSocket { @@ -95,8 +95,8 @@ impl NestriWebSocket { while let Some(message_result) = ws_read.next().await { match message_result { Ok(message) => { - let data = message.into_text().expect("failed to turn message into text"); - let base_message = match decode_message(data.to_string()) { + let data = message.into_data(); + let base_message = match decode_message(&data) { Ok(base_message) => base_message, Err(e) => { eprintln!("Failed to decode message: {:?}", e); @@ -107,14 +107,11 @@ impl NestriWebSocket { let callbacks_lock = callbacks.read().unwrap(); if let Some(callback) = callbacks_lock.get(&base_message.payload_type) { let data = data.clone(); - callback(data.to_string()); + callback(data); } } Err(e) => { - eprintln!( - "Error receiving message: {:?}, reconnecting in 3 seconds...", - e - ); + eprintln!("Error receiving message: {:?}, reconnecting in 3 seconds...", e); sleep(Duration::from_secs(3)).await; self_clone.reconnect().await.unwrap(); break; // Break the inner loop to get a new ws_read @@ -126,7 +123,7 @@ impl NestriWebSocket { }); } - fn spawn_write_loop(&self, mut message_rx: mpsc::UnboundedReceiver) { + fn spawn_write_loop(&self, mut message_rx: mpsc::UnboundedReceiver>) { let writer = self.writer.clone(); let self_clone = self.clone(); @@ -139,10 +136,7 @@ impl NestriWebSocket { let mut writer_lock = writer.lock().await; if let Some(writer) = writer_lock.as_mut() { // Try to send the message over the WebSocket - match writer - .send(Message::Text(Utf8Bytes::from(message.clone()))) - .await - { + match writer.send(Message::Binary(message.clone())).await { Ok(_) => { // Message sent successfully break; @@ -202,7 +196,7 @@ impl NestriWebSocket { } /// Send a message through the WebSocket - pub fn send_message(&self, message: String) -> Result<(), Box> { + pub fn send_message(&self, message: Vec) -> Result<(), Box> { self.message_tx .send(message) .map_err(|e| format!("Failed to send message: {:?}", e).into()) @@ -211,7 +205,7 @@ impl NestriWebSocket { /// Register a callback for a specific response type pub fn register_callback(&self, response_type: &str, callback: F) where - F: Fn(String) + Send + Sync + 'static, + F: Fn(Vec) + Send + Sync + 'static, { let mut callbacks_lock = self.callbacks.write().unwrap(); callbacks_lock.insert(response_type.to_string(), Box::new(callback)); @@ -240,7 +234,6 @@ impl Log for NestriWebSocket { let log_message = MessageLog { base: MessageBase { payload_type: "log".to_string(), - latency: None, }, level, message, diff --git a/protobufs/buf.yaml b/protobufs/buf.yaml deleted file mode 100644 index 534fcc92..00000000 --- a/protobufs/buf.yaml +++ /dev/null @@ -1,7 +0,0 @@ -version: v2 -breaking: - use: - - FILE -lint: - use: - - STANDARD diff --git a/protobufs/latency_tracker.proto b/protobufs/latency_tracker.proto deleted file mode 100644 index 6e56b573..00000000 --- a/protobufs/latency_tracker.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/timestamp.proto"; - -option go_package = "relay/internal/proto"; - -package proto; - -message ProtoTimestampEntry { - string stage = 1; - google.protobuf.Timestamp time = 2; -}; - -message ProtoLatencyTracker { - string sequence_id = 1; - repeated ProtoTimestampEntry timestamps = 2; -} \ No newline at end of file diff --git a/protobufs/messages.proto b/protobufs/messages.proto deleted file mode 100644 index 7617ccc0..00000000 --- a/protobufs/messages.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -option go_package = "relay/internal/proto"; - -import "types.proto"; -import "latency_tracker.proto"; - -package proto; - -message ProtoMessageBase { - string payload_type = 1; - ProtoLatencyTracker latency = 2; -} - -message ProtoMessageInput { - ProtoMessageBase message_base = 1; - ProtoInput data = 2; -} diff --git a/protobufs/types.proto b/protobufs/types.proto deleted file mode 100644 index c5a73a37..00000000 --- a/protobufs/types.proto +++ /dev/null @@ -1,63 +0,0 @@ -syntax = "proto3"; - -option go_package = "relay/internal/proto"; - -package proto; - -// MouseMove message -message ProtoMouseMove { - string type = 1; // Fixed value "MouseMove" - int32 x = 2; - int32 y = 3; -} - -// MouseMoveAbs message -message ProtoMouseMoveAbs { - string type = 1; // Fixed value "MouseMoveAbs" - int32 x = 2; - int32 y = 3; -} - -// MouseWheel message -message ProtoMouseWheel { - string type = 1; // Fixed value "MouseWheel" - int32 x = 2; - int32 y = 3; -} - -// MouseKeyDown message -message ProtoMouseKeyDown { - string type = 1; // Fixed value "MouseKeyDown" - int32 key = 2; -} - -// MouseKeyUp message -message ProtoMouseKeyUp { - string type = 1; // Fixed value "MouseKeyUp" - int32 key = 2; -} - -// KeyDown message -message ProtoKeyDown { - string type = 1; // Fixed value "KeyDown" - int32 key = 2; -} - -// KeyUp message -message ProtoKeyUp { - string type = 1; // Fixed value "KeyUp" - int32 key = 2; -} - -// Union of all Input types -message ProtoInput { - oneof input_type { - ProtoMouseMove mouse_move = 1; - ProtoMouseMoveAbs mouse_move_abs = 2; - ProtoMouseWheel mouse_wheel = 3; - ProtoMouseKeyDown mouse_key_down = 4; - ProtoMouseKeyUp mouse_key_up = 5; - ProtoKeyDown key_down = 6; - ProtoKeyUp key_up = 7; - } -} \ No newline at end of file