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.

279 lines
9.0 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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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, pingSerializer, getSerializer, setSerializer, pubSerializer, subSerializer) {
this.type = type;
this.pingSerializer = pingSerializer;
this.getSerializer = getSerializer;
this.setSerializer = setSerializer;
this.pubSerializer = pubSerializer;
this.subSerializer = subSerializer;
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 => {
console.log('ON CLOSE')
$(`${this.type}-btn-connect`).innerText = 'Connect';
this.setConnectedState(false);
this.subscribed = false;
};
});
$(`${this.type}-btn-ping`).addEventListener('click', event => {
event.preventDefault();
const serialized = this.pingSerializer();
this.send(serialized);
});
$(`${this.type}-btn-set`).addEventListener('click', event => {
event.preventDefault();
const serialized = this.setSerializer($(`${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.getSerializer($(`${this.type}-get-key`).value);
this.send(serialized);
});
$(`${this.type}-btn-pub`).addEventListener('click', event => {
event.preventDefault();
const serialized = this.pubSerializer($(`${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.subSerializer($(`${this.type}-sub-channel`).value);
try {
this.send(serialized);
this.subscribed = true;
this.setConnectedState(true);
} catch (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();
}
}
addEventListener("DOMContentLoaded", () => {
installBlock('JSON', 'json');
installBlock('Raw', 'raw');
const jsonClient = new Client('json',
() => JSON.stringify(['PING']),
(key) => JSON.stringify(['GET', key]),
(key, value) => JSON.stringify(['SET', key, value]),
(channel, message) => JSON.stringify(['PUBLISH', channel, message]),
(channel) => JSON.stringify(['SUBSCRIBE', channel]));
const rawClient = new Client('raw',
() => '*1\r\n$4\r\nPING\r\n',
(key) => `*2\r\n$3\r\nGET\r\n$${key.length}\r\n${key}\r\n`,
(key, value) => `*3\r\n$3\r\nSET\r\n$${key.length}\r\n${key}\r\n$${value.length}\r\n${value}\r\n`,
(channel, message) => `*3\r\n$7\r\nPUBLISH\r\n$${channel.length}\r\n${channel}\r\n$${message.length}\r\n${message}\r\n`,
(channel) => `*2\r\n$9\r\nSUBSCRIBE\r\n$${channel.length}\r\n${channel}\r\n`);
});
</script>
</body>
</html>