vail

Internet morse code repeater
git clone https://git.woozle.org/neale/vail.git

vail / static
Neale Pickett  ·  2024-10-22

protocol-demo.html

  1<!DOCTYPE html>
  2<html>
  3	<head>
  4		<title>Vail Protocol Demo</title>
  5		<style>
  6body {
  7	font-family: sans-serif;
  8}
  9
 10.log {
 11	font-family: monospace;
 12	max-height: 10em;
 13	overflow: scroll;
 14}
 15		</style>
 16		<script>
 17const Millisecond = 1
 18const Second = 1000 * Millisecond
 19
 20class Vail extends EventTarget {
 21	constructor(repeater, protocols=["json.vail.woozle.org"]) {
 22		super()
 23		this.url = new URL("wss://vail.woozle.org/chat")
 24		this.url.searchParams.set("repeater", repeater)
 25		this.protocols = protocols
 26		this.transmitters = 0
 27		this.reopen()
 28	}
 29
 30	reopen() {
 31		/** Number of clients connected */
 32		this.clients = 0
 33
 34		/** Timestamp offset for incoming messages */
 35		this.offset = 0
 36
 37		this.socket = new WebSocket(this.url, this.protocols)
 38		this.socket.addEventListener("open", event => {
 39			switch (this.socket.protocol) {
 40			case "json.vail.woozle.org":
 41				this.socket.addEventListener("message", event => this.jsonMessage(event))
 42				break
 43			case "binary.vail.woozle.org":
 44				this.socket.addEventListener("message", event => this.binaryMessage(event))
 45				break
 46			default:
 47				console.error("Unrecognized protocol:", this.socket.protocol)
 48			}
 49		})
 50		this.socket.addEventListener("close", event => {
 51			setTimeout(() => this.reopen(), 3 * Second)
 52		})
 53	}
 54
 55	jsonMessage(event) {
 56		log("#json", event.data)
 57	}
 58
 59	async binaryMessage(event) {
 60		let buf = await event.data.arrayBuffer()
 61		let view = new DataView(buf)
 62		let ts = view.getBigUint64(0)
 63		let clients = view.getUint16(8)
 64		let durations = []
 65		for (let i = 10; i < view.byteLength; i += 2) {
 66			durations.push(view.getUint16(i))
 67		}
 68		let raw = [...new Uint8Array(buf)].map(x => x.toString(16).padStart(2, 0)).join(" ")
 69
 70		log("#binary", `${raw} ts=${ts} cli=${clients} dur=${durations}`)
 71	}
 72}
 73
 74function log(selector, text) {
 75	let el = document.querySelector(selector)
 76	if (!el) {
 77		console.error("No match for selector", selector)
 78		return
 79	}
 80	let log = el.querySelector(".log")
 81	let line = log.appendChild(document.createElement("div"))
 82	line.textContent = text
 83	line.scrollIntoView()
 84}
 85
 86function init(repeater) {
 87	let cliJson = new Vail(repeater, ["json.vail.woozle.org"])
 88	let cliBin = new Vail(repeater, ["binary.vail.woozle.org"])
 89}
 90
 91init("demo")
 92		</script>
 93	</head>
 94	<body>
 95		<h1>Vail Protocol Demo</h1>
 96
 97		<div id="json">
 98			<h2>JSON</h2>
 99			<div class="log"></div>
100		</div>
101
102		<div id="binary">
103			<h2>Binary</h2>
104			<div class="log"></div>
105		</div>
106	</body>
107</html>