-
Notifications
You must be signed in to change notification settings - Fork 0
/
home.html
131 lines (122 loc) · 4.97 KB
/
home.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!doctype html>
<html>
<head>
<title>Client w/ Subscribers example</title>
<script>
var ws
window.onload = () => {
if ( ! window['WebSocket']) {
document.body.innerHTML = "Your browser doesn't support Websockets.";
return
}
const channelDiv = document.getElementById('channels')
ws = createWebSocket(channelDiv)
const output = document.getElementById('output')
const broadcast = document.getElementById('broadcast')
broadcast.addEventListener('click', broadcastMessage)
}
const createWebSocket = (channelDiv) => {
const ws = new WebSocket("ws://"+document.location.host+"/connect")
ws.onopen = ev => {
fetchAllChannels(channelDiv)
writeWebsocketIPToTitle()
}
ws.onclose = ev => {
doOutput("<strong>Broadcast closed</strong>")
}
ws.onmessage = ev => {
messageBroker(channelDiv, ev.data)
}
return ws
}
const messageBroker = (channelDiv, message) => {
const jsonMessage = JSON.parse(message)
if ( ! jsonMessage.type) {
throw Error("no message type in message " + message)
} else if (jsonMessage.type == "broadcast") {
doOutput(jsonMessage.body)
} else if (jsonMessage.type == "connect") {
addChannel(channelDiv, jsonMessage.body)
} else if (jsonMessage.type == "disconnect") {
removeChannel(channelDiv, jsonMessage.body)
} else {
throw Error("unknown message type: " + jsonMessage.type)
}
}
let channels = []
const fetchAllChannels = async channelDiv => {
channels = await fetch('/channels').then(response => response.json())
displayChannels(channelDiv)
}
const addChannel = (channelDiv, channel) => {
channels.push(channel)
displayChannels(channelDiv)
}
const removeChannel = (channelDiv, channel) => {
const index = channels.indexOf(channel)
if (index === -1) {
throw Error("channel not found for removal: " + channel)
}
channels.splice(index, 1)
displayChannels(channelDiv)
}
const displayChannels = (channelDiv) => {
channels.sort()
channelDiv.innerHTML = ''
channels.forEach(channel => {
const subscribeButton = document.createElement('button')
subscribeButton.innerText = channel
subscribeButton.addEventListener('click', subscribeTo)
const child = document.createElement('div')
child.appendChild(subscribeButton)
channelDiv.appendChild(child)
})
}
const subscribeTo = async ev => {
const ip = ev.target.innerHTML
await fetch('/subscribe?ip='+ip)
}
const broadcastMessage = () => {
const message = document.getElementById('message')
if (! message.value) {
return
}
ws.send(message.value)
message.value = ''
}
const doOutput = message => {
block = document.createElement('div')
block.innerHTML = message
output.appendChild(block)
}
const writeWebsocketIPToTitle = () => {
const ip = getCookie('ws-ip')
document.title = 'Client ' + ip
}
const getCookie = cookieName => {
const name = cookieName + "=";
const decodedCookie = decodeURIComponent(document.cookie);
const cookies = decodedCookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i];
while (cookie.charAt(0) == ' ') {
cookie = cookie.substring(1);
}
if (cookie.indexOf(name) == 0) {
return cookie.substring(name.length, cookie.length);
}
}
return "";
}
</script>
</head>
<body>
<h3>Avaliable Channels</h3>
<div id="channels"></div>
<h3>Selected Channel Output</h3>
<div id="output"></div>
<h3>Send to subscribers</h3>
<input id="message" type="text">
<button id="broadcast">Broadcast</button>
</body>
</html>