Try websockets
This commit is contained in:
parent
0ca02591bd
commit
03d7ac54d1
9 changed files with 579 additions and 59 deletions
323
Cargo.lock
generated
323
Cargo.lock
generated
|
@ -2,12 +2,48 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "1.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.10.0"
|
version = "3.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytes"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.10"
|
version = "0.1.10"
|
||||||
|
@ -30,6 +66,106 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "http"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"fnv",
|
||||||
|
"itoa",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "httparse"
|
||||||
|
version = "1.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.57"
|
version = "0.3.57"
|
||||||
|
@ -60,12 +196,30 @@ dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matches"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memory_units"
|
name = "memory_units"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.39"
|
version = "1.0.39"
|
||||||
|
@ -84,12 +238,59 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped-tls"
|
name = "scoped-tls"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.137"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha-1"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"cpufeatures",
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.96"
|
version = "1.0.96"
|
||||||
|
@ -101,21 +302,109 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tungstenite"
|
||||||
|
version = "0.17.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d96a2dea40e7570482f28eb57afbe42d97551905da6a9400acc5c328d24004f5"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"byteorder",
|
||||||
|
"bytes",
|
||||||
|
"http",
|
||||||
|
"httparse",
|
||||||
|
"log",
|
||||||
|
"rand",
|
||||||
|
"sha-1",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"utf-8",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usdpl"
|
name = "usdpl"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"usdpl-core",
|
"usdpl-core",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-test",
|
"wasm-bindgen-test",
|
||||||
|
"wasm-rs-shared-channel",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"wee_alloc",
|
"wee_alloc",
|
||||||
]
|
]
|
||||||
|
@ -124,6 +413,7 @@ dependencies = [
|
||||||
name = "usdpl-back"
|
name = "usdpl-back"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"tungstenite",
|
||||||
"usdpl-core",
|
"usdpl-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -135,6 +425,24 @@ version = "0.1.0"
|
||||||
name = "usdpl-rs"
|
name = "usdpl-rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf-8"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.80"
|
version = "0.2.80"
|
||||||
|
@ -225,6 +533,19 @@ dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-rs-shared-channel"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c555c35b5c51f5f134fb470b103435880fd7a9def4e830dc0081d8af5b09378b"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"js-sys",
|
||||||
|
"serde",
|
||||||
|
"thiserror",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.57"
|
version = "0.3.57"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "usdpl-back"
|
name = "usdpl-back"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
repository = "https://github.com/NGnius/usdpl-rs"
|
repository = "https://github.com/NGnius/usdpl-rs"
|
||||||
|
@ -14,3 +14,4 @@ crankshaft = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
||||||
|
tungstenite = { version = "0.17" }
|
||||||
|
|
6
usdpl-back/src/errors.rs
Normal file
6
usdpl-back/src/errors.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
pub enum ServerError {
|
||||||
|
Tungstenite(tungstenite::error::Error),
|
||||||
|
Io(std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ServerResult = Result<(), ServerError>;
|
|
@ -1,6 +1,9 @@
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream, SocketAddr};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Read, Write};
|
//use std::io::{Read, Write};
|
||||||
|
|
||||||
|
use tungstenite::accept;
|
||||||
|
use tungstenite::protocol::{Message, WebSocket};
|
||||||
|
|
||||||
use usdpl_core::serdes::{Dumpable, Loadable, Primitive};
|
use usdpl_core::serdes::{Dumpable, Loadable, Primitive};
|
||||||
use usdpl_core::{RemoteCallResponse, socket};
|
use usdpl_core::{RemoteCallResponse, socket};
|
||||||
|
@ -27,7 +30,7 @@ impl<'a> Instance<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_packet<const ERROR: bool>(&mut self, packet: socket::Packet, buffer: &mut [u8], incoming: &mut TcpStream) -> std::io::Result<()> {
|
fn handle_packet<const ERROR: bool>(&mut self, packet: socket::Packet, buffer: &mut [u8], incoming: &mut WebSocket<TcpStream>, peer_addr: &SocketAddr) -> super::ServerResult {
|
||||||
match packet {
|
match packet {
|
||||||
socket::Packet::Call(obj) => {
|
socket::Packet::Call(obj) => {
|
||||||
if let Some(target_func) = self.calls.get_mut(&obj.function) {
|
if let Some(target_func) = self.calls.get_mut(&obj.function) {
|
||||||
|
@ -39,18 +42,22 @@ impl<'a> Instance<'a> {
|
||||||
});
|
});
|
||||||
let (ok, len) = response.dump(buffer);
|
let (ok, len) = response.dump(buffer);
|
||||||
if !ok && ERROR {
|
if !ok && ERROR {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump return value of function `{}`", &obj.function)));
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump return value of function `{}`", &obj.function))));
|
||||||
}
|
}
|
||||||
if ERROR {
|
if ERROR {
|
||||||
incoming.write(&buffer[..len])?;
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).map_err(super::ServerError::Tungstenite)?;
|
||||||
} else {
|
} else {
|
||||||
incoming.write(&buffer[..len]).unwrap_or_default();
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).unwrap_or_default();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ERROR {
|
if ERROR {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid remote call `{}` received from {}", obj.function, incoming.peer_addr()?)));
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid remote call `{}` received from {}", obj.function, peer_addr))));
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Invalid remote call `{}` received from {}", obj.function, incoming.peer_addr()?);
|
eprintln!("Invalid remote call `{}` received from {}", obj.function, peer_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,54 +67,89 @@ impl<'a> Instance<'a> {
|
||||||
if let socket::Packet::Many(_) = packet {
|
if let socket::Packet::Many(_) = packet {
|
||||||
// drop nested socket packets (prevents DoS and bad practices)
|
// drop nested socket packets (prevents DoS and bad practices)
|
||||||
if ERROR {
|
if ERROR {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid nested Many packet received from {}", incoming.peer_addr()?)));
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid nested Many packet received from {}", peer_addr))));
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Invalid nested Many packet received from {}", incoming.peer_addr()?);
|
eprintln!("Invalid nested Many packet received from {}", peer_addr);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
self.handle_packet::<ERROR>(packet, buffer, incoming)?;
|
self.handle_packet::<ERROR>(packet, buffer, incoming, peer_addr)?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let (ok, len) = socket::Packet::Unsupported.dump(buffer);
|
let (ok, len) = socket::Packet::Unsupported.dump(buffer);
|
||||||
if !ok && ERROR {
|
if !ok && ERROR {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump unsupported packet")));
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Cannot dump unsupported packet"))));
|
||||||
}
|
}
|
||||||
if ERROR {
|
if ERROR {
|
||||||
incoming.write(&buffer[..len])?;
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).map_err(super::ServerError::Tungstenite)?;
|
||||||
} else {
|
} else {
|
||||||
incoming.write(&buffer[..len]).unwrap_or_default();
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).unwrap_or_default();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serve<const ERROR: bool>(&mut self) -> std::io::Result<()> {
|
pub fn serve<const ERROR: bool>(&mut self) -> super::ServerResult {
|
||||||
let result = self.serve_internal::<ERROR>();
|
let result = self.serve_internal::<ERROR>();
|
||||||
//println!("Stopping server due to serve_internal returning a result");
|
//println!("Stopping server due to serve_internal returning a result");
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Receive and execute callbacks forever
|
/// Receive and execute callbacks forever
|
||||||
pub fn serve_internal<const ERROR: bool>(&mut self) -> std::io::Result<()> {
|
pub fn serve_internal<const ERROR: bool>(&mut self) -> super::ServerResult {
|
||||||
let listener = TcpListener::bind(socket::socket_addr(self.port))?;
|
let listener = TcpListener::bind(socket::socket_addr(self.port)).map_err(super::ServerError::Io)?;
|
||||||
for incoming in listener.incoming() {
|
|
||||||
let mut incoming = incoming?;
|
|
||||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||||
let len = incoming.read(&mut buffer)?;
|
for incoming in listener.incoming() {
|
||||||
let (obj_maybe, _) = socket::Packet::load(&buffer[..len]);
|
let incoming = incoming.map_err(super::ServerError::Io)?;
|
||||||
|
let peer_addr = incoming.peer_addr().map_err(super::ServerError::Io)?;
|
||||||
|
let mut incoming = match accept(incoming) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
match incoming.read_message() {
|
||||||
|
Err(e) => if ERROR {
|
||||||
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid message received from {}: {}", peer_addr, e))));
|
||||||
|
} else {
|
||||||
|
eprintln!("Invalid message received from {}: {}", peer_addr, e);
|
||||||
|
},
|
||||||
|
Ok(Message::Binary(bin)) => {
|
||||||
|
let (obj_maybe, _) = socket::Packet::load(bin.as_slice());
|
||||||
if let Some(packet) = obj_maybe {
|
if let Some(packet) = obj_maybe {
|
||||||
self.handle_packet::<ERROR>(packet, &mut buffer, &mut incoming)?;
|
self.handle_packet::<ERROR>(packet, &mut buffer, &mut incoming, &peer_addr)?;
|
||||||
} else {
|
} else {
|
||||||
if ERROR {
|
if ERROR {
|
||||||
return Err(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid packet received from {}", incoming.peer_addr()?)));
|
return Err(super::ServerError::Io(std::io::Error::new(std::io::ErrorKind::Unsupported, format!("Invalid packet received from {}", peer_addr))));
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Invalid packet received from {}", incoming.peer_addr()?);
|
eprintln!("Invalid packet received from {}", peer_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Ok(_) => {
|
||||||
|
let (_, len) = socket::Packet::Unsupported.dump(&mut buffer);
|
||||||
|
if ERROR {
|
||||||
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).map_err(super::ServerError::Tungstenite)?;
|
||||||
|
} else {
|
||||||
|
let mut vec = Vec::with_capacity(len);
|
||||||
|
vec.extend_from_slice(&buffer[..len]);
|
||||||
|
incoming.write_message(Message::Binary(vec)).unwrap_or_default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
incoming.close(None).map_err(super::ServerError::Tungstenite)?;
|
||||||
|
'endless: loop {
|
||||||
|
match incoming.read_message() {
|
||||||
|
Err(tungstenite::error::Error::ConnectionClosed) => break 'endless,
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
incoming.shutdown(std::net::Shutdown::Both)?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -115,15 +157,15 @@ impl<'a> Instance<'a> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::net::TcpStream;
|
//use std::net::TcpStream;
|
||||||
use super::*;
|
//use super::*;
|
||||||
|
|
||||||
const PORT: u16 = 31337;
|
//const PORT: u16 = 31337;
|
||||||
|
|
||||||
#[test]
|
/*#[test]
|
||||||
fn serve_full_test() -> std::io::Result<()> {
|
fn serve_full_test() -> std::io::Result<()> {
|
||||||
let _server = std::thread::spawn(|| {
|
let _server = std::thread::spawn(|| {
|
||||||
Instance::new(PORT, PORT + 80)
|
Instance::new(PORT)
|
||||||
.register("echo".to_string(), &mut |params| params)
|
.register("echo".to_string(), &mut |params| params)
|
||||||
.register("hello".to_string(), &mut |params| {
|
.register("hello".to_string(), &mut |params| {
|
||||||
if let Some(Primitive::String(name)) = params.get(0) {
|
if let Some(Primitive::String(name)) = params.get(0) {
|
||||||
|
@ -176,7 +218,7 @@ mod tests {
|
||||||
front.write(&buffer[..len]).unwrap();
|
front.write(&buffer[..len]).unwrap();
|
||||||
let _ = front.read(&mut buffer).unwrap();
|
let _ = front.read(&mut buffer).unwrap();
|
||||||
});
|
});
|
||||||
Instance::new(PORT+1, PORT+1+80)
|
Instance::new(PORT+1)
|
||||||
.register("echo".to_string(), &mut |params| params)
|
.register("echo".to_string(), &mut |params| params)
|
||||||
.register("hello".to_string(), &mut |params| {
|
.register("hello".to_string(), &mut |params| {
|
||||||
if let Some(Primitive::String(name)) = params.get(0) {
|
if let Some(Primitive::String(name)) = params.get(0) {
|
||||||
|
@ -193,7 +235,7 @@ mod tests {
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn serve_unsupported_test() {
|
fn serve_unsupported_test() {
|
||||||
let _server = std::thread::spawn(|| {
|
let _server = std::thread::spawn(|| {
|
||||||
Instance::new(PORT+2, PORT+2+80)
|
Instance::new(PORT+2)
|
||||||
.register("echo".to_string(), &mut |params| params)
|
.register("echo".to_string(), &mut |params| params)
|
||||||
.register("hello".to_string(), &mut |params| {
|
.register("hello".to_string(), &mut |params| {
|
||||||
if let Some(Primitive::String(name)) = params.get(0) {
|
if let Some(Primitive::String(name)) = params.get(0) {
|
||||||
|
@ -220,5 +262,5 @@ mod tests {
|
||||||
} else {
|
} else {
|
||||||
panic!("Wrong response packet type");
|
panic!("Wrong response packet type");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
//! This is a minimalist TCP server for handling events from the front-end.
|
//! This is a minimalist TCP server for handling events from the front-end.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
mod errors;
|
||||||
mod instance;
|
mod instance;
|
||||||
|
|
||||||
pub use instance::Instance;
|
pub use instance::Instance;
|
||||||
|
pub use errors::{ServerError, ServerResult};
|
||||||
|
|
||||||
pub mod core {
|
pub mod core {
|
||||||
pub use usdpl_core::*;
|
pub use usdpl_core::*;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "usdpl"
|
name = "usdpl"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
@ -17,7 +17,7 @@ decky = []
|
||||||
crankshaft = []
|
crankshaft = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasm-bindgen = "0.2.63"
|
wasm-bindgen = "0.2"
|
||||||
|
|
||||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||||
# logging them with `console.error`. This is great for development, but requires
|
# logging them with `console.error`. This is great for development, but requires
|
||||||
|
@ -32,8 +32,9 @@ console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||||
wee_alloc = { version = "0.4.5", optional = true }
|
wee_alloc = { version = "0.4.5", optional = true }
|
||||||
|
|
||||||
web-sys = { version = "0.3", features = ["TcpSocket"] }
|
web-sys = { version = "0.3", features = ["WebSocket", "MessageEvent", "ErrorEvent", "BinaryType"] }
|
||||||
js-sys = { version = "0.3" }
|
js-sys = { version = "0.3" }
|
||||||
|
wasm-rs-shared-channel = { version = "0.1" }
|
||||||
|
|
||||||
usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
usdpl-core = { version = "0.1.0", path = "../usdpl-core" }
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,49 @@
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use web_sys::TcpSocket;
|
use wasm_bindgen::prelude::*;
|
||||||
use js_sys::{ArrayBuffer, DataView};
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
|
use web_sys::{WebSocket, MessageEvent, ErrorEvent};
|
||||||
|
use js_sys::{ArrayBuffer, DataView, Uint8Array};
|
||||||
|
use wasm_rs_shared_channel::{Expects, spsc::{Receiver, Sender}};
|
||||||
|
|
||||||
use usdpl_core::socket;
|
use usdpl_core::socket;
|
||||||
use usdpl_core::serdes::{Dumpable, Loadable};
|
use usdpl_core::serdes::{Dumpable, Loadable};
|
||||||
|
|
||||||
|
use super::imports;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn send(packet: socket::Packet, port: u16) -> bool {
|
/// Send packet over a Javascript socket
|
||||||
let socket = match TcpSocket::new(socket::HOST_STR, port) {
|
pub(crate) fn send_js(packet: socket::Packet, port: u16) -> Option<socket::Packet> {
|
||||||
|
let addr = format!("wss://{}:{}", socket::HOST_STR, port);
|
||||||
|
let socket = match WebSocket::new(&addr) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return false,
|
Err(e) => {
|
||||||
|
imports::console_error(
|
||||||
|
&format!("USDPL error: TcpSocket::new(...) failed with error {}",
|
||||||
|
js_sys::JSON::stringify(&e)
|
||||||
|
.map(|x| x.as_string().unwrap_or("WTF".into()))
|
||||||
|
.unwrap_or("unknown error".into())));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
socket.set_binary_type(web_sys::BinaryType::Arraybuffer);
|
||||||
|
let (tx, rx) : (Sender<_>, Receiver<_>) = wasm_rs_shared_channel::spsc::channel(socket::PACKET_BUFFER_SIZE as u32 + 4).split();
|
||||||
|
|
||||||
|
let onmessage_callback = Closure::wrap(Box::new(onmessage_factory(tx)) as Box<dyn FnMut(MessageEvent)>);
|
||||||
|
socket.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
|
||||||
|
//onmessage_callback.forget();
|
||||||
|
|
||||||
|
let onerror_callback = Closure::wrap(Box::new(onerror_factory()) as Box<dyn FnMut(ErrorEvent)>);
|
||||||
|
socket.set_onerror(Some(onerror_callback.as_ref().unchecked_ref()));
|
||||||
|
//onerror_callback.forget();
|
||||||
|
|
||||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||||
let (ok, len) = packet.dump(&mut buffer);
|
let (ok, len) = packet.dump(&mut buffer);
|
||||||
if !ok {
|
if !ok {
|
||||||
return false;
|
imports::console_error("USDPL error: packet dump failed");
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
// copy to JS buffer
|
// copy to JS buffer
|
||||||
let array_buffer = ArrayBuffer::new(len as u32);
|
let array_buffer = ArrayBuffer::new(len as u32);
|
||||||
|
@ -25,28 +52,136 @@ pub(crate) fn send(packet: socket::Packet, port: u16) -> bool {
|
||||||
dataview.set_uint8(i, buffer[i]);
|
dataview.set_uint8(i, buffer[i]);
|
||||||
}
|
}
|
||||||
match socket.send_with_array_buffer(&array_buffer) {
|
match socket.send_with_array_buffer(&array_buffer) {
|
||||||
Ok(b) => b,
|
Ok(_) => {},
|
||||||
Err(_) => false
|
Err(e) => {
|
||||||
|
imports::console_error(&format!("USDPL error: socket send_with_array_buffer(...) failed -- {:?}", e));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let result = match rx.recv(Some(std::time::Duration::from_secs(60))) {
|
||||||
|
Ok(Some(val)) => {
|
||||||
|
socket::Packet::load(&val.1[..val.0 as _]).0
|
||||||
|
},
|
||||||
|
Ok(None) => {
|
||||||
|
imports::console_error(&format!("USDPL error: SharedChannel recv timed out"));
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
imports::console_error(&format!("USDPL error: got SharedChannel recv error -- {:?}", e));
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
socket.close().unwrap_or(());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn onmessage_factory(sender: Sender<Sendable<{socket::PACKET_BUFFER_SIZE}>>) -> impl FnMut(MessageEvent) {
|
||||||
|
move |e: MessageEvent| {
|
||||||
|
if let Ok(buf) = e.data().dyn_into::<js_sys::ArrayBuffer>() {
|
||||||
|
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||||
|
let dataview = DataView::new(&buf, 0, buf.byte_length() as _);
|
||||||
|
for i in 0..buf.byte_length() as usize {
|
||||||
|
if i < socket::PACKET_BUFFER_SIZE {
|
||||||
|
buffer[i] = dataview.get_uint8(i);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Err(e) = sender.send(&Sendable(buf.byte_length(), buffer)) {
|
||||||
|
imports::console_error(&format!("USDPL error: got SharedChannel send error {:?}", e));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
imports::console_warn(&format!("USDPL warning: Got non-data message from {}", e.origin()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn onerror_factory() -> impl FnMut(ErrorEvent) {
|
||||||
|
move |e: ErrorEvent| {
|
||||||
|
imports::console_error(&format!("USDPL error: got socket error {}", e.message()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
/// Send packet over a WASM-native TCP socket
|
||||||
pub(crate) fn send_native(packet: socket::Packet, port: u16) -> Option<socket::Packet> {
|
pub(crate) fn send_native(packet: socket::Packet, port: u16) -> Option<socket::Packet> {
|
||||||
let mut socket = match TcpStream::connect(socket::socket_addr(port)) {
|
let mut socket = match TcpStream::connect(socket::socket_addr(port)) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => return None,
|
Err(e) => {
|
||||||
|
imports::console_error(&format!("USDPL error: TcpStream failed to connect with error {}", e));
|
||||||
|
return None;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
|
||||||
let (ok, len) = packet.dump(&mut buffer);
|
let (ok, len) = packet.dump(&mut buffer);
|
||||||
if !ok {
|
if !ok {
|
||||||
|
imports::console_error("USDPL error: packet dump failed");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match socket.write(&buffer[..len]) {
|
match socket.write(&buffer[..len]) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(_) => return None
|
Err(e) => {
|
||||||
|
imports::console_error(&format!("USDPL error: socket write failed with error {}", e));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let len = match socket.read(&mut buffer) {
|
let len = match socket.read(&mut buffer) {
|
||||||
Ok(len) => len,
|
Ok(len) => len,
|
||||||
Err(_) => return None
|
Err(e) => {
|
||||||
|
imports::console_error(&format!("USDPL error: socket read failed with error {}", e));
|
||||||
|
return None;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
socket::Packet::load(&buffer[..len]).0
|
socket::Packet::load(&buffer[..len]).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Sendable<const SIZE: usize>(u32, [u8; SIZE]);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SendableError(String);
|
||||||
|
|
||||||
|
impl std::error::Error for SendableError {}
|
||||||
|
|
||||||
|
impl std::fmt::Display for SendableError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
(&self.0 as &dyn std::fmt::Display).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const SIZE: usize> wasm_rs_shared_channel::Shareable for Sendable<SIZE> {
|
||||||
|
type Error = SendableError;
|
||||||
|
|
||||||
|
fn to_bytes(&self) -> Result<Uint8Array, Self::Error> {
|
||||||
|
let array = Uint8Array::new_with_length(SIZE as u32 + 4);
|
||||||
|
let mut cursor = 0;
|
||||||
|
for byte in self.0.to_le_bytes() {
|
||||||
|
array.set_index(cursor, byte);
|
||||||
|
cursor += 1;
|
||||||
|
}
|
||||||
|
for byte in self.1 {
|
||||||
|
array.set_index(cursor, byte);
|
||||||
|
cursor += 1;
|
||||||
|
}
|
||||||
|
Ok(array)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from(bytes: &Uint8Array) -> Result<Result<Self, Expects>, Self::Error> {
|
||||||
|
if bytes.length() < 4 {
|
||||||
|
return Err(SendableError("Too small for size int".into()));
|
||||||
|
}
|
||||||
|
let len = u32::from_le_bytes([
|
||||||
|
bytes.get_index(0),
|
||||||
|
bytes.get_index(1),
|
||||||
|
bytes.get_index(2),
|
||||||
|
bytes.get_index(3),
|
||||||
|
]);
|
||||||
|
if bytes.length() < len + 4 {
|
||||||
|
return Err(SendableError("Too small for buffer".into()));
|
||||||
|
}
|
||||||
|
let mut buf = [0u8; SIZE];
|
||||||
|
for i in 0..len {
|
||||||
|
buf[i as usize] = bytes.get_index(4 + i);
|
||||||
|
}
|
||||||
|
Ok(Ok(Sendable(len, buf)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
usdpl-front/src/imports.rs
Normal file
13
usdpl-front/src/imports.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||||
|
pub fn console_log(s: &str);
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_namespace = console, js_name = warn)]
|
||||||
|
pub fn console_warn(s: &str);
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_namespace = console, js_name = error)]
|
||||||
|
pub fn console_error(s: &str);
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
mod connection;
|
mod connection;
|
||||||
mod convert;
|
mod convert;
|
||||||
|
mod imports;
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
@ -18,11 +19,6 @@ const REMOTE_PORT: std::sync::atomic::AtomicU16 = std::sync::atomic::AtomicU16::
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
extern {
|
|
||||||
//fn alert(s: &str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initialize the front-end library
|
/// Initialize the front-end library
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn init_usdpl(port: u16) -> bool {
|
pub fn init_usdpl(port: u16) -> bool {
|
||||||
|
@ -52,13 +48,16 @@ pub fn call_backend(name: String, parameters: Vec<JsValue>) -> Option<Vec<JsValu
|
||||||
for val in parameters {
|
for val in parameters {
|
||||||
params.push(convert::js_to_primitive(val));
|
params.push(convert::js_to_primitive(val));
|
||||||
}
|
}
|
||||||
let results = match connection::send_native(Packet::Call(RemoteCall {
|
let results = match connection::send_js(Packet::Call(RemoteCall {
|
||||||
id: next_id,
|
id: next_id,
|
||||||
function: name,
|
function: name,
|
||||||
parameters: params,
|
parameters: params,
|
||||||
}), REMOTE_PORT.load(std::sync::atomic::Ordering::Relaxed)) {
|
}), REMOTE_PORT.load(std::sync::atomic::Ordering::Relaxed)) {
|
||||||
Some(Packet::CallResponse(resp)) => resp,
|
Some(Packet::CallResponse(resp)) => resp,
|
||||||
_ => return None,
|
_ => {
|
||||||
|
imports::console_error("USDPL error: connection::send_native(...) returned None");
|
||||||
|
return None
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let mut js_results = Vec::with_capacity(results.response.len());
|
let mut js_results = Vec::with_capacity(results.response.len());
|
||||||
for val in results.response {
|
for val in results.response {
|
||||||
|
|
Loading…
Reference in a new issue