mirror of
https://github.com/uqbar-dao/nectar.git
synced 2025-01-03 06:11:01 +03:00
chess work
This commit is contained in:
parent
5a4813b8c4
commit
84a5bbbe6c
@ -62,7 +62,7 @@ snow = { version = "0.9.3", features = ["ring-resolver"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] }
|
||||
tokio-tungstenite = "*"
|
||||
url = "*"
|
||||
url = "2.4.1"
|
||||
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "e53c124" }
|
||||
uuid = { version = "1.1.2", features = ["serde", "v4"] }
|
||||
warp = "0.3.5"
|
||||
|
92
modules/chess/Cargo.lock
generated
92
modules/chess/Cargo.lock
generated
@ -50,6 +50,12 @@ version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -124,6 +130,21 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[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.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
@ -162,12 +183,33 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "id-arena"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
@ -234,6 +276,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pleco"
|
||||
version = "0.5.0"
|
||||
@ -532,12 +580,42 @@ dependencies = [
|
||||
"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.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
@ -553,16 +631,30 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
[[package]]
|
||||
name = "uqbar_process_lib"
|
||||
version = "0.3.0"
|
||||
source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=db26c5b#db26c5b1607ba6532bcc7687bf8902a21ebd3393"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"http",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"url",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
@ -17,7 +17,7 @@ bincode = "1.3.3"
|
||||
pleco = "0.5"
|
||||
serde = {version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
uqbar_process_lib = { path = "../../../process_lib" }
|
||||
uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "db26c5b" }
|
||||
wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" }
|
||||
|
||||
[lib]
|
||||
|
@ -1,79 +0,0 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import json
|
||||
import glob
|
||||
import shutil
|
||||
|
||||
def compile_process(process_dir, pkg_dir, root_dir):
|
||||
# Get the path to the source code and the compiled WASM file
|
||||
src_path = os.path.join(process_dir, "src")
|
||||
wasm_path = os.path.join(pkg_dir, os.path.basename(process_dir) + ".wasm")
|
||||
|
||||
# Check if the source code or the Cargo.toml file has been modified since the last compile
|
||||
src_mtime = max(os.path.getmtime(f) for f in glob.glob(os.path.join(src_path, '**'), recursive=True))
|
||||
wasm_mtime = os.path.getmtime(wasm_path) if os.path.exists(wasm_path) else 0
|
||||
|
||||
# Change to the process directory
|
||||
os.chdir(process_dir)
|
||||
|
||||
# Create the target/bindings/$name/ directory
|
||||
bindings_dir = os.path.join(process_dir, "target", "bindings", os.path.basename(process_dir))
|
||||
os.makedirs(bindings_dir, exist_ok=True)
|
||||
|
||||
# Create target.wasm (compiled .wit) & world
|
||||
subprocess.check_call([
|
||||
"wasm-tools", "component", "wit",
|
||||
os.path.join(root_dir, "wit"),
|
||||
"-o", os.path.join(bindings_dir, "target.wasm"),
|
||||
"--wasm"
|
||||
])
|
||||
|
||||
# Copy /wit (world is empty file currently)
|
||||
shutil.copytree(os.path.join(root_dir, "wit"), os.path.join(bindings_dir, "wit"), dirs_exist_ok=True)
|
||||
# shutil.copy(os.path.join(root_dir, "world"), os.path.join(bindings_dir, "world"))
|
||||
|
||||
# Create an empty world file
|
||||
with open(os.path.join(bindings_dir, "world"), 'w') as f:
|
||||
pass
|
||||
|
||||
# Build the module using Cargo
|
||||
subprocess.check_call([
|
||||
"cargo", "+nightly", "build",
|
||||
"--release",
|
||||
"--no-default-features",
|
||||
"--target", "wasm32-wasi"
|
||||
])
|
||||
|
||||
# Adapt the module using wasm-tools
|
||||
wasm_file = os.path.join(process_dir, "target", "wasm32-wasi", "release", os.path.basename(process_dir) + ".wasm")
|
||||
adapted_wasm_file = wasm_file.replace(".wasm", "_adapted.wasm")
|
||||
subprocess.check_call([
|
||||
"wasm-tools", "component", "new",
|
||||
wasm_file,
|
||||
"-o", adapted_wasm_file,
|
||||
"--adapt", os.path.join(root_dir, "wasi_snapshot_preview1.wasm")
|
||||
])
|
||||
|
||||
# Embed "wit" into the component and place it in the expected location
|
||||
subprocess.check_call([
|
||||
"wasm-tools", "component", "embed", os.path.join(root_dir, "wit"),
|
||||
"--world", "process",
|
||||
adapted_wasm_file,
|
||||
"-o", wasm_path
|
||||
])
|
||||
|
||||
if __name__ == "__main__":
|
||||
root_dir = os.getcwd()
|
||||
pkg_dir = os.path.join(root_dir, "pkg")
|
||||
|
||||
# If a specific process is provided, compile it
|
||||
if len(sys.argv) > 1:
|
||||
process_dir = os.path.abspath(os.path.join(root_dir, sys.argv[1]))
|
||||
compile_process(process_dir, pkg_dir, root_dir)
|
||||
else:
|
||||
# Compile each base dir folder that has a Cargo.toml
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
if 'Cargo.toml' in files and "process_lib" not in root:
|
||||
process_dir = os.path.abspath(root)
|
||||
compile_process(process_dir, pkg_dir, root_dir)
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"package": "chess2",
|
||||
"package": "chess",
|
||||
"publisher": "uqbar",
|
||||
"version": [0, 1, 0]
|
||||
"version": [0, 2, 0]
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
82
modules/chess/src/utils.rs
Normal file
82
modules/chess/src/utils.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::*;
|
||||
|
||||
pub fn save_chess_state(state: &ChessState) {
|
||||
let stored_state = convert_state(&state);
|
||||
set_state(&bincode::serialize(&stored_state).unwrap());
|
||||
}
|
||||
|
||||
fn convert_game(game: Game) -> StoredGame {
|
||||
StoredGame {
|
||||
id: game.id,
|
||||
turns: game.turns,
|
||||
board: game.board.fen(),
|
||||
white: game.white,
|
||||
black: game.black,
|
||||
ended: game.ended,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_state(state: &ChessState) -> StoredChessState {
|
||||
StoredChessState {
|
||||
games: state
|
||||
.games
|
||||
.iter()
|
||||
.map(|(id, game)| (id.to_string(), convert_game(game.clone())))
|
||||
.collect(),
|
||||
records: state.records.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json_game(game: &Game) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"id": game.id,
|
||||
"turns": game.turns,
|
||||
"board": game.board.fen(),
|
||||
"white": game.white,
|
||||
"black": game.black,
|
||||
"ended": game.ended,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn send_ws_update(our: &Address, game: &Game) -> anyhow::Result<()> {
|
||||
Request::new()
|
||||
.target((&our.node, "http_server", "sys", "uqbar"))
|
||||
.ipc(
|
||||
serde_json::json!({
|
||||
"EncryptAndForward": {
|
||||
"channel_id": our.process.to_string(),
|
||||
"forward_to": {
|
||||
"node": our.node.clone(),
|
||||
"process": {
|
||||
"process_name": "http_server",
|
||||
"package_name": "sys",
|
||||
"publisher_node": "uqbar"
|
||||
}
|
||||
}, // node, process
|
||||
"json": Some(serde_json::json!({ // this is the JSON to forward
|
||||
"WebSocketPush": {
|
||||
"target": {
|
||||
"node": our.node.clone(),
|
||||
"id": "chess", // If the message passed in an ID then we could send to just that ID
|
||||
}
|
||||
}
|
||||
})),
|
||||
}
|
||||
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
.payload(Payload {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
"kind": "game_update",
|
||||
"data": json_game(game),
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
})
|
||||
.send()
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import json
|
||||
import base64
|
||||
import os
|
||||
import shutil
|
||||
import http.client
|
||||
from urllib.parse import urlparse
|
||||
|
||||
### helpers
|
||||
def send_request(path, json_data):
|
||||
conn = http.client.HTTPConnection(HOST, PORT)
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
conn.request("POST", path, json_data, headers)
|
||||
|
||||
response = conn.getresponse()
|
||||
|
||||
conn.close()
|
||||
return response
|
||||
|
||||
def new_package(package_name, publisher_node, zip_file):
|
||||
request = {
|
||||
"node": NODE,
|
||||
"process": "main:app_store:uqbar",
|
||||
"inherit": False,
|
||||
"expects_response": None,
|
||||
"ipc": json.dumps({
|
||||
"NewPackage": {
|
||||
"package": {"package_name": package_name, "publisher_node": publisher_node },
|
||||
"mirror": True
|
||||
}
|
||||
}),
|
||||
"metadata": None,
|
||||
"context": None,
|
||||
"mime": "application/zip",
|
||||
"data": zip_file
|
||||
}
|
||||
return json.dumps(request)
|
||||
|
||||
|
||||
def install_package(package_name, publisher_node):
|
||||
request = {
|
||||
"node": NODE,
|
||||
"process": "main:app_store:uqbar",
|
||||
"inherit": False,
|
||||
"expects_response": None,
|
||||
"ipc": json.dumps({
|
||||
"Install": {"package_name": package_name, "publisher_node": publisher_node },
|
||||
}),
|
||||
"metadata": None,
|
||||
"context": None,
|
||||
"mime": None,
|
||||
"data": None,
|
||||
}
|
||||
return json.dumps(request)
|
||||
|
||||
# zip a directory
|
||||
def zip_directory(directory, zip_filename):
|
||||
shutil.make_archive(zip_filename, 'zip', directory)
|
||||
|
||||
# encode a file with base64
|
||||
def encode_file_in_base64(file_path):
|
||||
with open(file_path, 'rb') as file:
|
||||
return base64.b64encode(file.read()).decode('utf-8')
|
||||
|
||||
|
||||
|
||||
|
||||
# check if there are enough parameters provided.
|
||||
if len(sys.argv) < 3 or len(sys.argv) > 4:
|
||||
print("Usage: python3 start-package.py <url> <pkg-dir> [node-id]")
|
||||
sys.exit(1)
|
||||
|
||||
URL = sys.argv[1]
|
||||
PKG_DIR = os.path.abspath(sys.argv[2])
|
||||
|
||||
# If NODE is provided, use it. Otherwise, set it to None.
|
||||
NODE = sys.argv[3] if len(sys.argv) == 4 else None
|
||||
|
||||
parsed_url = urlparse(URL)
|
||||
HOST = parsed_url.hostname
|
||||
PORT = parsed_url.port
|
||||
|
||||
# parse metadata.json to get the package and publisher
|
||||
with open(f"{PKG_DIR}/metadata.json", 'r') as f:
|
||||
metadata = json.load(f)
|
||||
|
||||
PACKAGE = metadata['package']
|
||||
PUBLISHER = metadata['publisher']
|
||||
PKG_PUBLISHER = f"{PACKAGE}:{PUBLISHER}"
|
||||
|
||||
print(PKG_PUBLISHER)
|
||||
|
||||
# create zip and put it in /target
|
||||
parent_dir = os.path.dirname(PKG_DIR)
|
||||
parent_dir = os.path.abspath(parent_dir)
|
||||
os.makedirs(os.path.join(parent_dir, 'target'), exist_ok=True)
|
||||
|
||||
zip_filename = os.path.join(parent_dir, 'target', PKG_PUBLISHER)
|
||||
zip_directory(PKG_DIR, zip_filename)
|
||||
|
||||
|
||||
encoded_zip_file = encode_file_in_base64(zip_filename + '.zip')
|
||||
|
||||
|
||||
# create a new package
|
||||
new_pkg = new_package(PACKAGE, PUBLISHER, encoded_zip_file)
|
||||
res = send_request("/rpc:sys:uqbar/message", new_pkg)
|
||||
|
||||
if not res.status == 200:
|
||||
print("Failed to send new package request, status: ", res.status)
|
||||
sys.exit(1)
|
||||
|
||||
# install/start/reboot the package
|
||||
install_pkg = install_package(PACKAGE, PUBLISHER)
|
||||
|
||||
resp = send_request("/rpc:sys:uqbar/message", install_pkg)
|
||||
if not resp.status == 200:
|
||||
print("Failed to send install package request, status: ", resp.status)
|
||||
sys.exit(1)
|
||||
|
||||
print("Successfully installed package: ", PKG_PUBLISHER)
|
||||
sys.exit(0)
|
Binary file not shown.
@ -177,6 +177,12 @@ async fn http_handler(
|
||||
) -> Result<impl warp::Reply, warp::Rejection> {
|
||||
// TODO this is all so dirty. Figure out what actually matters.
|
||||
|
||||
println!(
|
||||
"http_server: got request from {:?} for {}\r",
|
||||
socket_addr,
|
||||
path.as_str()
|
||||
);
|
||||
|
||||
// trim trailing "/"
|
||||
let original_path = normalize_path(path.as_str());
|
||||
let id: u64 = rand::random();
|
||||
@ -188,6 +194,8 @@ async fn http_handler(
|
||||
};
|
||||
let bound_path = route.handler();
|
||||
|
||||
println!("here1\r");
|
||||
|
||||
if bound_path.authenticated {
|
||||
let auth_token = serialized_headers
|
||||
.get("cookie")
|
||||
@ -198,6 +206,8 @@ async fn http_handler(
|
||||
}
|
||||
}
|
||||
|
||||
println!("here2\r");
|
||||
|
||||
let is_local = socket_addr
|
||||
.map(|addr| addr.ip().is_loopback())
|
||||
.unwrap_or(false);
|
||||
@ -206,6 +216,8 @@ async fn http_handler(
|
||||
return Ok(warp::reply::with_status(vec![], StatusCode::FORBIDDEN).into_response());
|
||||
}
|
||||
|
||||
println!("here3\r");
|
||||
|
||||
// if path has static content, serve it
|
||||
if let Some(static_content) = &bound_path.static_content {
|
||||
return Ok(warp::http::Response::builder()
|
||||
@ -221,6 +233,8 @@ async fn http_handler(
|
||||
.into_response());
|
||||
}
|
||||
|
||||
println!("here4\r");
|
||||
|
||||
// RPC functionality: if path is /rpc:sys:uqbar/message,
|
||||
// we extract message from base64 encoded bytes in data
|
||||
// and send it to the correct app.
|
||||
@ -376,7 +390,7 @@ async fn handle_rpc_message(
|
||||
async fn maintain_websocket(
|
||||
ws: WebSocket,
|
||||
our: Arc<String>,
|
||||
jwt_secret_bytes: Arc<Vec<u8>>,
|
||||
_jwt_secret_bytes: Arc<Vec<u8>>,
|
||||
ws_senders: WebSocketSenders,
|
||||
send_to_loop: MessageSender,
|
||||
) {
|
||||
@ -386,7 +400,7 @@ async fn maintain_websocket(
|
||||
// channel and verify their identity using JWT. Then we can forward their
|
||||
// messages to a specific process.
|
||||
|
||||
let owner_process: ProcessId = todo!();
|
||||
let owner_process: ProcessId = ProcessId::new(Some("chess"), "chess2", "uqbar");
|
||||
|
||||
let ws_channel_id: u64 = rand::random();
|
||||
let (ws_sender, mut ws_receiver) = tokio::sync::mpsc::channel(100);
|
||||
@ -399,17 +413,44 @@ async fn maintain_websocket(
|
||||
None => {
|
||||
// stream closed, remove and exit
|
||||
websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
// stream error, remove and exit
|
||||
println!("http_server websocket channel error: {e}");
|
||||
websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
Some(Ok(msg)) => {
|
||||
// forward message to process associated with this channel
|
||||
todo!();
|
||||
let _ = send_to_loop
|
||||
.send(KernelMessage {
|
||||
id: rand::random(),
|
||||
source: Address {
|
||||
node: our.to_string(),
|
||||
process: HTTP_SERVER_PROCESS_ID.clone(),
|
||||
},
|
||||
target: Address {
|
||||
node: our.to_string(),
|
||||
process: owner_process.clone(),
|
||||
},
|
||||
rsvp: None,
|
||||
message: Message::Request(Request {
|
||||
inherit: false,
|
||||
expects_response: None,
|
||||
ipc: serde_json::to_vec(&HttpServerAction::WebSocketPush {
|
||||
channel_id: ws_channel_id,
|
||||
message_type: WsMessageType::Binary,
|
||||
}).unwrap(),
|
||||
metadata: None,
|
||||
}),
|
||||
payload: Some(Payload {
|
||||
mime: None,
|
||||
bytes: msg.into_bytes(),
|
||||
}),
|
||||
signed_capabilities: None,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,12 +462,14 @@ async fn maintain_websocket(
|
||||
// stream error, remove and exit
|
||||
println!("http_server websocket channel error: {e}");
|
||||
websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let stream = write_stream.reunite(read_stream).unwrap();
|
||||
let _ = stream.close().await;
|
||||
}
|
||||
|
||||
async fn websocket_close(
|
||||
@ -601,7 +644,6 @@ async fn handle_app_message(
|
||||
} => {
|
||||
let mut path_bindings = path_bindings.write().await;
|
||||
if km.source.process != "homepage:homepage:uqbar" {
|
||||
// TODO ???
|
||||
path = if path.starts_with('/') {
|
||||
format!("/{}{}", km.source.process, path)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user