Skip to content

Commit

Permalink
Replace websockets with fastwebsockets.
Browse files Browse the repository at this point in the history
This includes an update of hyper, and a change of the protocol.
Specifically, the websocket connection does not require a separate port
but instead is done via /ws. Furthermore, the client does not poll for
frames anymore, instead it sets a preferred frame rate.
  • Loading branch information
H-M-H committed Sep 24, 2024
1 parent 70f337c commit cdf648a
Show file tree
Hide file tree
Showing 12 changed files with 914 additions and 1,166 deletions.
520 changes: 133 additions & 387 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ description = "Use your iPad or Android tablet as graphic tablet."
[dependencies]
autopilot = { git = "https://github.com/H-M-H/autopilot-rs.git", rev = "63eed09c715bfb665bb23172a3930a528e11691c" }
bitflags = "^1.3"
bytes = "1.7.1"
dirs = "^4.0"
fastwebsockets = { version = "0.8.0", features = ["upgrade", "unstable-split"] }
fltk = { version = "^1", features = ["no-pango"] }
handlebars = "^4.1"
hyper = { version = "^0.14", features = ["server", "tcp", "http1", "http2"] }
http-body-util = "0.1.2"
hyper = { version = "^1.4", features = ["server", "http1", "http2"] }
hyper-util = { version = "0.1.8", features = ["tokio"] }
image = { version = "^0.23", features = ["png"], default-features = false }
image_autopilot = { package = "image", version = "0.22.5", features = [], default-features = false }
percent-encoding = "2.1.0"
Expand All @@ -21,12 +25,11 @@ serde = { version = "^1.0", features = ["derive"] }
serde_json = "^1.0"
signal-hook = "0.3.17"
structopt = { version = "^0.3", features = ["color", "suggestions"], default-features = false }
tokio = { version = "^1", features = ["macros", "rt-multi-thread", "sync"] }
tokio = { version = "^1", features = ["fs", "macros", "rt-multi-thread", "sync"] }
toml = "^0.5"
tracing = "^0.1"
tracing-subscriber = { version = "^0.3", features = ["ansi", "json"], default-features = false }
url = "^2.2"
websocket = { version = "=0.26.2", features = ["sync"], default-features = false }

[build-dependencies]
cc = "^1.0"
Expand Down
10 changes: 5 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::fs;
use std::net::IpAddr;
use std::{fs, path::PathBuf};

use serde::{Deserialize, Serialize};
use structopt::StructOpt;
Expand Down Expand Up @@ -69,16 +69,16 @@ pub struct Config {
help = "Use custom template of index.html to be served by Weylus."
)]
#[serde(skip)]
pub custom_index_html: Option<String>,
pub custom_index_html: Option<PathBuf>,
#[structopt(long, help = "Use custom access.html to be served by Weylus.")]
#[serde(skip)]
pub custom_access_html: Option<String>,
pub custom_access_html: Option<PathBuf>,
#[structopt(long, help = "Use custom style.css to be served by Weylus.")]
#[serde(skip)]
pub custom_style_css: Option<String>,
pub custom_style_css: Option<PathBuf>,
#[structopt(long, help = "Use custom lib.js to be served by Weylus.")]
#[serde(skip)]
pub custom_lib_js: Option<String>,
pub custom_lib_js: Option<PathBuf>,

#[structopt(long, help = "Print shell completions for given shell.")]
#[serde(skip)]
Expand Down
56 changes: 28 additions & 28 deletions src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use fltk::{
use pnet_datalink as datalink;

use crate::config::{write_config, Config};
use crate::websocket::Ws2UiMessage;
use crate::web::Web2UiMessage::UInputInaccessible;

pub fn run(config: &Config, log_receiver: mpsc::Receiver<String>) {
let width = 200;
Expand Down Expand Up @@ -218,33 +218,29 @@ pub fn run(config: &Config, log_receiver: mpsc::Receiver<String>) {
config.try_mediafoundation = check_native_hw_accel.is_checked();
}
}
if !weylus.start(
&config,
|_| {},
|message| match message {
Ws2UiMessage::UInputInaccessible => {
let w = 500;
let h = 300;
let mut pop_up = Window::default()
.with_size(w, h)
.center_screen()
.with_label("Weylus - UInput inaccessible!");
pop_up.set_xclass("weylus");

let buf = TextBuffer::default();
let mut pop_up_text = TextDisplay::default().with_size(w, h);
pop_up_text.set_buffer(buf);
pop_up_text.wrap_mode(fltk::text::WrapMode::AtBounds, 5);
let mut buf = pop_up_text.buffer().unwrap();
buf.set_text(std::include_str!("strings/uinput_error.txt"));

pop_up.end();
pop_up.make_modal(true);
pop_up.show();
}
_ => {}
},
) {
if !weylus.start(&config, |message| match message {
UInputInaccessible => {
let w = 500;
let h = 300;
let mut pop_up = Window::default()
.with_size(w, h)
.center_screen()
.with_label("Weylus - UInput inaccessible!");
pop_up.set_xclass("weylus");

let buf = TextBuffer::default();
let mut pop_up_text = TextDisplay::default().with_size(w, h);
pop_up_text.set_buffer(buf);
pop_up_text.wrap_mode(fltk::text::WrapMode::AtBounds, 5);
let mut buf = pop_up_text.buffer().unwrap();
buf.set_text(std::include_str!("strings/uinput_error.txt"));

pop_up.end();
pop_up.make_modal(true);
pop_up.show();
}
_ => {}
}) {
return Ok(());
}
is_server_running = true;
Expand Down Expand Up @@ -349,4 +345,8 @@ pub fn run(config: &Config, log_receiver: mpsc::Receiver<String>) {
but_toggle.set_callback(toggle_server);

app.run().expect("Failed to run Gui!");

// TODO: Remove when https://github.com/fltk-rs/fltk-rs/issues/1480 is fixed
// this is required to drop the callback and do a graceful shutdown of the web server
but_toggle.set_callback(|_| ());
}
14 changes: 5 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,11 @@ fn main() {

if conf.no_gui {
let mut weylus = crate::weylus::Weylus::new();
weylus.start(
&conf,
|_| {},
|msg| {
if let crate::websocket::Ws2UiMessage::UInputInaccessible = msg {
warn!(std::include_str!("strings/uinput_error.txt"));
}
},
);
weylus.start(&conf, |msg| {
if let crate::web::Web2UiMessage::UInputInaccessible = msg {
warn!(std::include_str!("strings/uinput_error.txt"));
}
});
#[cfg(unix)]
{
let mut signals = Signals::new(TERM_SIGNALS).unwrap();
Expand Down
18 changes: 14 additions & 4 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ pub struct ClientConfiguration {
pub max_width: usize,
pub max_height: usize,
pub client_name: Option<String>,
pub frame_rate: f64,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum MessageInbound {
PointerEvent(PointerEvent),
WheelEvent(WheelEvent),
KeyboardEvent(KeyboardEvent),
// request a video frame from the server
// like this the client can partially control the framerate by sending requests at some given
// rate. However, the server may drop a request if encoding is too slow.
TryGetFrame,
GetCapturableList,
Config(ClientConfiguration),
}
Expand Down Expand Up @@ -151,3 +148,16 @@ pub struct WheelEvent {
pub dy: i32,
pub timestamp: u64,
}

pub trait WeylusSender {
type Error: std::error::Error;
fn send_message(&mut self, message: MessageOutbound) -> Result<(), Self::Error>;
fn send_video(&mut self, bytes: &[u8]) -> Result<(), Self::Error>;
}

pub trait WeylusReceiver: Iterator<Item = Result<MessageInbound, Self::Error>> {
type Error: std::error::Error;
fn recv_message(&mut self) -> Option<Result<MessageInbound, Self::Error>> {
self.next()
}
}
4 changes: 2 additions & 2 deletions src/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub struct VideoEncoder {
height_in: usize,
width_out: usize,
height_out: usize,
write_data: Box<dyn Fn(&[u8])>,
write_data: Box<dyn FnMut(&[u8])>,
start_time: Instant,
}

Expand All @@ -80,7 +80,7 @@ impl VideoEncoder {
height_in: usize,
width_out: usize,
height_out: usize,
write_data: impl Fn(&[u8]) + 'static,
mut write_data: impl FnMut(&[u8]) + 'static,
options: EncoderOptions,
) -> Result<Box<Self>, CError> {
let mut video_encoder = Box::new(Self {
Expand Down
Loading

0 comments on commit cdf648a

Please sign in to comment.