aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client-web/source/helper.ts25
-rw-r--r--client-web/source/local_user.ts7
-rw-r--r--client-web/source/preferences.ts16
-rw-r--r--client-web/source/protocol/mod.ts6
-rw-r--r--client-web/source/room.ts17
-rw-r--r--server/src/main.rs6
-rw-r--r--server/src/protocol.rs56
-rw-r--r--server/src/room.rs35
8 files changed, 77 insertions, 91 deletions
diff --git a/client-web/source/helper.ts b/client-web/source/helper.ts
index ef95e3a..c277c0d 100644
--- a/client-web/source/helper.ts
+++ b/client-web/source/helper.ts
@@ -4,3 +4,28 @@ export function hex_id(len = 8): string {
if (len > 8) return hex_id() + hex_id(len - 8)
return Math.floor(Math.random() * 16 ** len).toString(16).padStart(len, "0")
}
+
+const elem = (s: string) => document.createElement(s)
+const elem_with_content = (s: string) => (c: string) => {
+ const e = elem(s)
+ e.textContent = c
+ return e
+}
+const elem_with_children = (s: string) => (opts: { classes?: string[] }, ...cs: (HTMLElement | string)[]) => {
+ const e = elem(s)
+ if (opts.classes) e.classList.add(...opts.classes)
+ for (const c of cs) {
+ e.append(c)
+ }
+ return e
+}
+
+export const ep = elem_with_content("p")
+export const eh1 = elem_with_content("h1")
+export const eh2 = elem_with_content("h2")
+export const eh3 = elem_with_content("h3")
+export const eh4 = elem_with_content("h4")
+export const eh5 = elem_with_content("h5")
+export const eh6 = elem_with_content("h6")
+export const ediv = elem_with_children("div")
+
diff --git a/client-web/source/local_user.ts b/client-web/source/local_user.ts
index 85a2a23..bb5b779 100644
--- a/client-web/source/local_user.ts
+++ b/client-web/source/local_user.ts
@@ -69,17 +69,20 @@ export class LocalUser extends User {
document.body.append(el)
}
-
async create_camera_track() {
log("media", "requesting user media (camera)")
- const user_media = await window.navigator.mediaDevices.getUserMedia({ video: true })
+ const user_media = await window.navigator.mediaDevices.getUserMedia({
+ video: { facingMode: { ideal: PREFS.camera_facing_mode } }
+ })
return new TrackHandle(user_media.getVideoTracks()[0], true)
}
+
async create_screencast_track() {
log("media", "requesting user media (screen)")
const user_media = await window.navigator.mediaDevices.getDisplayMedia({ video: true })
return new TrackHandle(user_media.getVideoTracks()[0], true)
}
+
async create_mic_track() {
log("media", "requesting user media (audio)")
const audio_contraints = PREFS.rnnoise ? {
diff --git a/client-web/source/preferences.ts b/client-web/source/preferences.ts
index e7fc7bb..63efeb2 100644
--- a/client-web/source/preferences.ts
+++ b/client-web/source/preferences.ts
@@ -1,9 +1,12 @@
+import { hex_id } from "./helper.ts";
export interface PrefDecl<T> {
name: string,
- default: T
+ default: T,
+ type?: Type,
description: string,
possible_values?: T[]
+ optional?: boolean,
}
type Type = "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
@@ -13,7 +16,9 @@ export function register_prefs<T extends Record<string, PrefDecl<unknown>>>(ds:
const p: PrefMap<T> = {} as PrefMap<T>
for (const key in ds) {
const d = ds[key];
- let value = get_param(d.default, d.name) ?? d.default;
+ let type = typeof d.default;
+ if (type == "undefined") { if (d.type) type = d.type; else throw new Error("type needed"); }
+ let value = get_param(type, d.name) ?? d.default;
if (d.possible_values) if (!d.possible_values.includes(value)) value = d.default
p[key] = value
}
@@ -31,10 +36,9 @@ export function load_query_params(): { [key: string]: string } {
return q
}
-export function get_param<T>(example: T, key: string): T | undefined {
+export function get_param<T>(ty: string, key: string): T | undefined {
const v = raw_params[key]
if (v == undefined) return undefined
- const ty = typeof example
if (ty == "string") return v as unknown as T
else if (ty == "number") {
const n = parseInt(v)
@@ -50,14 +54,14 @@ export function get_param<T>(example: T, key: string): T | undefined {
return undefined
}
-
const PREF_DECLS = {
rnnoise: { name: "rnnoise", default: true, description: "Use RNNoise for noise suppression" },
native_noise_suppression: { name: "native_noise_suppression", default: false, description: "Suggest the browser to do noise suppression" },
- username: { name: "username", default: "guest", description: "Username" },
+ username: { name: "username", default: "guest-" + hex_id(), description: "Username" },
microphone_gain: { name: "microphone_gain", default: 1, description: "Amplify microphone volume" },
microphone_enabled: { name: "microphone_enabled", default: false, description: "Add one microphone track on startup" },
camera_enabled: { name: "camera_enabled", default: false, description: "Add one camera track on startup" },
screencast_enabled: { name: "screencast_enabled", default: false, description: "Add one screencast track on startup" },
+ camera_facing_mode: { name: "camera_facing_mode", default: undefined as undefined | string, type: "string" as const, possible_values: ["environment", "user", undefined], description: "Prefer user-facing or env-facing camera" }
}
export const PREFS = register_prefs(PREF_DECLS)
diff --git a/client-web/source/protocol/mod.ts b/client-web/source/protocol/mod.ts
new file mode 100644
index 0000000..76b1290
--- /dev/null
+++ b/client-web/source/protocol/mod.ts
@@ -0,0 +1,6 @@
+
+export class SignalingConnection {
+ constructor(room: string) {
+
+ }
+}
diff --git a/client-web/source/room.ts b/client-web/source/room.ts
index c22a956..78454bb 100644
--- a/client-web/source/room.ts
+++ b/client-web/source/room.ts
@@ -5,7 +5,8 @@ import { RemoteUser } from "./remote_user.ts";
import { User } from "./user.ts";
import { LocalUser } from "./local_user.ts";
import { ServerboundPacket, ClientboundPacket } from "../../common/packets.d.ts";
-
+import { PREFS } from "./preferences.ts";
+import { ep } from "./helper.ts";
export class Room {
el: HTMLElement
@@ -20,9 +21,19 @@ export class Room {
this.name = name
this.el = document.createElement("div")
this.el.classList.add("room")
- this.websocket = new WebSocket(`${window.location.protocol.endsWith("s:") ? "wss" : "ws"}://${window.location.host}/${encodeURIComponent(name)}/signaling`)
+
+ const ws_url = new URL(`${window.location.protocol.endsWith("s:") ? "wss" : "ws"}://${window.location.host}/${encodeURIComponent(name)}/signaling`)
+ ws_url.searchParams.set("username", PREFS.username)
+ this.websocket = new WebSocket(ws_url)
this.websocket.onclose = () => this.websocket_close()
- this.websocket.onopen = () => this.websocket_open()
+
+ // const connecting_text = ep("Upgrading to a websocket connection…")
+ // this.el.append(connecting_text)
+
+ this.websocket.onopen = () => {
+ // connecting_text.remove()
+ this.websocket_open()
+ }
this.websocket.onmessage = (ev) => {
this.websocket_message(JSON.parse(ev.data))
}
diff --git a/server/src/main.rs b/server/src/main.rs
index 268e2a4..12039c3 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -41,8 +41,10 @@ async fn run() {
let index = warp::path!().and(warp::fs::file("../client-web/public/start.html"));
let assets = warp::path("_assets").and(warp::fs::dir("../client-web/public/assets"));
- let routes = warp::get()
- .and(assets.or(app).or(index).or(signaling))
+ let routes = assets
+ .or(app)
+ .or(index)
+ .or(signaling)
.recover(handle_rejection)
.with(warp::log("stuff"));
diff --git a/server/src/protocol.rs b/server/src/protocol.rs
index f480ce7..5fb1ecb 100644
--- a/server/src/protocol.rs
+++ b/server/src/protocol.rs
@@ -3,21 +3,10 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ClientboundPacket {
- Init {
- your_id: usize,
- version: String,
- },
- ClientJoin {
- id: usize,
- name: String,
- },
- ClientLeave {
- id: usize,
- },
- Message {
- sender: usize,
- message: RelayMessage,
- },
+ Init { your_id: usize, version: String },
+ ClientJoin { id: usize },
+ ClientLeave { id: usize },
+ Message { sender: usize, message: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -26,41 +15,6 @@ pub enum ServerboundPacket {
Ping,
Relay {
recipient: Option<usize>,
- message: RelayMessage,
+ message: String,
},
}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-pub enum RelayMessage {
- Offer(RTCSessionDescriptionInit),
- Answer(RTCSessionDescriptionInit),
- IceCandidate(RTCIceCandidateInit),
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(rename_all = "snake_case")]
-pub enum RTCSdpType {
- Answer,
- Offer,
- PRAnswer,
- Rollback,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct RTCSessionDescriptionInit {
- sdp: String,
- #[serde(rename = "type")]
- ty: RTCSdpType,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct RTCIceCandidateInit {
- candidate: Option<String>,
- #[serde(rename = "sdpMLineIndex")]
- sdp_mline_index: Option<i32>,
- #[serde(rename = "sdpMid")]
- sdp_mid: Option<String>,
- #[serde(rename = "usernameFragment")]
- username_fragment: Option<String>,
-}
diff --git a/server/src/room.rs b/server/src/room.rs
index db545a6..53479ef 100644
--- a/server/src/room.rs
+++ b/server/src/room.rs
@@ -5,16 +5,10 @@ use std::{collections::HashMap, sync::atomic::AtomicUsize};
use tokio::sync::{mpsc, RwLock};
use warp::ws::{Message, WebSocket};
-#[derive(Debug)]
-pub struct Client {
- pub name: String,
- pub out: mpsc::UnboundedSender<ClientboundPacket>,
-}
-
#[derive(Debug, Default)]
pub struct Room {
pub id_counter: AtomicUsize,
- pub clients: RwLock<HashMap<usize, Client>>,
+ pub clients: RwLock<HashMap<usize, mpsc::UnboundedSender<ClientboundPacket>>>,
}
impl Room {
@@ -29,14 +23,7 @@ impl Room {
let id = self
.id_counter
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
- let name = format!("user no. {id}");
- g.insert(
- id,
- Client {
- out: tx,
- name: name.clone(),
- },
- );
+ g.insert(id, tx);
drop(g);
debug!("assigned id={id}, init connection");
@@ -62,20 +49,14 @@ impl Room {
.await;
// send join of this client to all clients
- self.broadcast(None, ClientboundPacket::ClientJoin { id, name })
+ self.broadcast(None, ClientboundPacket::ClientJoin { id })
.await;
// send join of all other clients to this one
- for (&cid, c) in self.clients.read().await.iter() {
+ for (&cid, _) in self.clients.read().await.iter() {
// skip self
if cid != id {
- self.send_to_client(
- id,
- ClientboundPacket::ClientJoin {
- id: cid,
- name: c.name.clone(),
- },
- )
- .await;
+ self.send_to_client(id, ClientboundPacket::ClientJoin { id: cid })
+ .await;
}
}
debug!("client should be ready!");
@@ -108,13 +89,13 @@ impl Room {
pub async fn broadcast(&self, sender: Option<usize>, packet: ClientboundPacket) {
for (&id, tx) in self.clients.read().await.iter() {
if sender != Some(id) {
- let _ = tx.out.send(packet.clone());
+ let _ = tx.send(packet.clone());
}
}
}
pub async fn send_to_client(&self, recipient: usize, packet: ClientboundPacket) {
if let Some(c) = self.clients.read().await.get(&recipient) {
- let _ = c.out.send(packet);
+ let _ = c.send(packet);
}
}