chef-socket
Version:
static files server + websockets = chef-socket
91 lines (74 loc) • 2.15 kB
HTML
<html>
<head>
<meta charset="utf-8" />
<title>Chat</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no"
/>
<style>
body,
input {
font-family: monospace;
}
img.bear {
width: 20%;
max-width: 200px;
float: right;
}
</style>
</head>
<body>
<img src="./chef.svg" class="bear" />
<h1>Chat</h1>
<p><strong>Your username:</strong> <span id="username"></span></p>
<form id="chat" autocomplete="off">
<input type="text" id="message" />
<button type="submit">send</button>
</form>
<p><strong>Messages:</strong></p>
<div id="messages"></div>
<script
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.0/socket.io.js"
></script>
<script type="text/javascript">
const socket = new io(location.origin.replace(/^http/, "ws"), {
transports: ["websocket"],
});
const refs = getHTMLElements();
socket.on("connect", () => {
// step 1 ~> 2 of flow - send handshake of plugin name
socket.emit("/join", "chat");
});
socket.onAny((event, id, data) => {
// append output
const string = [id, event, data].filter(Boolean).join(" > ");
refs.messages.innerHTML += `<div>${string}</div>\n`;
});
socket.on("/join", (id) => {
// first join is your join, set your server named id
if (!refs.username.innerText) {
refs.username.innerText = id;
}
});
refs.chat.addEventListener("submit", (event) => {
event.preventDefault();
const payload = refs.message.value.trim();
if (!payload) return;
socket.emit("say", payload);
refs.message.value = "";
});
function getHTMLElements() {
return ["username", "messages", "message", "chat"].reduce(
(obj, id) => ({
...obj,
[id]: document.querySelector(`#${id}`),
}),
{},
);
}
</script>
</body>
</html>