You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
273 lines
8.4 KiB
HTML
273 lines
8.4 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>WebSocket example</title>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous">
|
|
<style type="text/css">
|
|
h1, h3 {
|
|
text-align: center;
|
|
}
|
|
|
|
pre.sent, pre.received {
|
|
margin-top: 0px;
|
|
border-radius: 4px;
|
|
padding: 5px;
|
|
}
|
|
|
|
pre.sent {
|
|
border: 1px solid #4b63cc;
|
|
background-color: white;
|
|
}
|
|
|
|
pre.received {
|
|
border: 1px solid #4db96d;
|
|
text-align: right;
|
|
}
|
|
|
|
.ws-state {
|
|
font-weight: bold;
|
|
line-height: 18px;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
div.log {
|
|
font-size: 13pt;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="pure-g">
|
|
<h1 class="pure-u-1">Webdis with HTML5 WebSockets</h1>
|
|
</div>
|
|
|
|
<div class="pure-g">
|
|
<div class="pure-u-1-8"></div>
|
|
<div class="pure-u-1-3" id="json-container"></div>
|
|
|
|
<!-- spacer -->
|
|
<div class="pure-u-1-12"></div>
|
|
|
|
<div class="pure-u-1-3" id="raw-container"></div>
|
|
<div class="pure-u-1-8"></div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
$ = function(id) {return document.getElementById(id);};
|
|
const host = "127.0.0.1";
|
|
const port = 7379;
|
|
|
|
function installBlock(title, type) {
|
|
const contents = `
|
|
<h3>$TITLE</h3>
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-2-3"><label class="ws-state pure-u-23-24" id="$type-state">State: Disconnected</label></div>
|
|
<div class="pure-u-1-3"><button type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-connect">Connect</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-2-3"> </div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-ping">Ping</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="key" id="$type-set-key" value="hello" /></div>
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="value" id="$type-set-value" value="world" /></div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-set">SET</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-1-3"> </div>
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="key" id="$type-get-key" value="hello" /></div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-get">GET</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="channel name" id="$type-pub-channel" value="channel-0" /></div>
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="message value" id="$type-pub-message" value="message-0" /></div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-pub">PUBLISH</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
|
|
<form class="pure-form">
|
|
<fieldset>
|
|
<div class="pure-g">
|
|
<div class="pure-u-1-3"> </div>
|
|
<div class="pure-u-1-3"><input disabled class="pure-u-23-24" type="text" placeholder="channel" id="$type-sub-channel" value="channel-0" /></div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-sub">SUBSCRIBE</button></div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
|
|
<div class="pure-g">
|
|
<div class="pure-u-2-3"> </div>
|
|
<div class="pure-u-1-3"><button disabled type="submit" class="pure-u-23-24 pure-button pure-button-primary" id="$type-btn-clear">Clear logs</button></div>
|
|
<div class="log pure-u-1-1" id="$type-log">
|
|
</div>
|
|
</div>
|
|
`;
|
|
$(`${type}-container`).innerHTML = contents.replace(/\$TITLE/g, title).replace(/\$type/g, type);
|
|
}
|
|
|
|
|
|
class Client {
|
|
constructor(type, serializer) {
|
|
this.type = type;
|
|
this.serializer = serializer;
|
|
this.ws = null;
|
|
this.connected = false;
|
|
this.subscribed = false;
|
|
this.logCount = 0;
|
|
|
|
$(`${this.type}-btn-connect`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
console.log('Connecting...');
|
|
this.ws = new WebSocket(`ws://${host}:${port}/.${this.type}`);
|
|
window.ws = this.ws;
|
|
this.ws.onopen = event => {
|
|
console.log('Connected');
|
|
this.setConnectedState(true);
|
|
};
|
|
|
|
// log received messages
|
|
this.ws.onmessage = messageEvent => {
|
|
this.log("received", messageEvent.data);
|
|
};
|
|
|
|
this.ws.onclose = event => {
|
|
$(`${this.type}-btn-connect`).innerText = 'Connect';
|
|
this.setConnectedState(false);
|
|
this.subscribed = false;
|
|
};
|
|
});
|
|
|
|
$(`${this.type}-btn-ping`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
const serialized = this.serializer(['PING']);
|
|
this.send(serialized);
|
|
});
|
|
|
|
$(`${this.type}-btn-set`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
const serialized = this.serializer(['SET', $(`${this.type}-set-key`).value, $(`${this.type}-set-value`).value]);
|
|
this.send(serialized);
|
|
});
|
|
|
|
$(`${this.type}-btn-get`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
const serialized = this.serializer(['GET', $(`${this.type}-get-key`).value]);
|
|
this.send(serialized);
|
|
});
|
|
|
|
$(`${this.type}-btn-pub`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
const serialized = this.serializer(['PUBLISH', $(`${this.type}-pub-channel`).value, $(`${this.type}-pub-message`).value]);
|
|
this.send(serialized);
|
|
});
|
|
|
|
$(`${this.type}-btn-sub`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
const serialized = this.serializer(['SUBSCRIBE', $(`${this.type}-sub-channel`).value]);
|
|
try {
|
|
this.send(serialized);
|
|
this.subscribed = true;
|
|
this.setConnectedState(true);
|
|
} catch (e) {
|
|
console.log('Error sending: ', serialized, e);
|
|
}
|
|
});
|
|
|
|
$(`${this.type}-btn-clear`).addEventListener('click', event => {
|
|
event.preventDefault();
|
|
$(`${this.type}-log`).innerText = "";
|
|
this.logCount = 0;
|
|
this.updateLogButton();
|
|
});
|
|
}
|
|
|
|
send(serialized) {
|
|
this.log("sent", serialized);
|
|
this.ws.send(serialized);
|
|
}
|
|
|
|
setConnectedState(connected) {
|
|
this.connected = connected;
|
|
$(`${this.type}-btn-connect`).disabled = connected;
|
|
$(`${this.type}-btn-ping`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-set-key`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-set-value`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-btn-set`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-get-key`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-btn-get`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-pub-channel`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-pub-message`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-btn-pub`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-sub-channel`).disabled = !connected || this.subscribed;
|
|
$(`${this.type}-btn-sub`).disabled = !connected || this.subscribed;
|
|
|
|
$(`${this.type}-state`).innerText = `State: ${connected ? 'Connected' : 'Disconnected'}`;
|
|
}
|
|
|
|
updateLogButton() {
|
|
$(`${this.type}-btn-clear`).disabled = this.logCount === 0;
|
|
}
|
|
|
|
log(dir, msg) {
|
|
const id = `${this.type}-log`;
|
|
|
|
const description = document.createElement("div");
|
|
description.innerHTML = dir;
|
|
$(id).appendChild(description);
|
|
|
|
const contents = document.createElement("pre");
|
|
contents.setAttribute("class", dir);
|
|
contents.innerHTML = msg;
|
|
$(id).appendChild(contents);
|
|
this.logCount++;
|
|
this.updateLogButton();
|
|
}
|
|
}
|
|
|
|
function serializeRaw(args) {
|
|
let raw = `*${args.length}\r\n`;
|
|
for (let i = 0; i < args.length; i++) {
|
|
raw += `$${args[i].length}\r\n`;
|
|
raw += `${args[i]}\r\n`;
|
|
}
|
|
return raw;
|
|
}
|
|
|
|
addEventListener("DOMContentLoaded", () => {
|
|
installBlock('JSON', 'json');
|
|
installBlock('Raw', 'raw');
|
|
|
|
const jsonClient = new Client('json', JSON.stringify);
|
|
const rawClient = new Client('raw', serializeRaw);
|
|
});
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|