Skip to content

Commit ab0aabe

Browse files
committed
update due to wol-client
1 parent bf2b377 commit ab0aabe

3 files changed

Lines changed: 105 additions & 45 deletions

File tree

src/wol.js

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const express = require("express")
22
const wss = require("./wss")
3+
const WebSocket = require("ws")
34

45
const { logger } = require("./utils/logger")
56
const { ENV } = require("./env")
@@ -101,30 +102,29 @@ function getDataByHostname(hostname) {
101102
}
102103
}
103104

104-
async function trySendWakeupPackets(hosts, wolUrl) {
105-
if (!hosts?.length) return null
106-
if (typeof wolUrl !== "string" || wolUrl.trim() === "") return null
105+
async function trySendWakeupPackets(client, hosts, wolUrl) {
106+
if (!hosts?.length) return { err: true }
107+
if (!client) return { err: true }
108+
if (!wolUrl) return { err: true }
107109

108-
let output = ""
109110
let err = false
110111

112+
const baseURL = new URL(wolUrl)
113+
const protocol = baseURL.protocol === "https:" ? "wss" : "ws"
114+
111115
const virtualPort =
112116
ENV.virtualPort && `${ENV.virtualPort}`.trim() !== ""
113117
? ENV.virtualPort
114118
: null
115119

116120
for (const host of hosts) {
117-
const ip = host.ip
118-
119121
let targetUrl = wolUrl
120122
let payload
121123

122124
if (host.isVirtual) {
123-
if (!virtualPort) {
124-
continue
125-
}
125+
if (!virtualPort) continue
126126

127-
targetUrl = `http://${ip}:${virtualPort}`
127+
targetUrl = `http://${host.ip}:${virtualPort}`
128128
payload = {
129129
id: host.id,
130130
startupTime: host.startupTime,
@@ -142,26 +142,90 @@ async function trySendWakeupPackets(hosts, wolUrl) {
142142
)
143143

144144
const response = await post(targetUrl, payload)
145-
if (!response?.message) {
145+
if (!response?.client_id) {
146146
err = true
147+
148+
sendToClient(client, {
149+
success: false,
150+
error: true,
151+
message: `WoL request failed`,
152+
})
153+
154+
errorClient(client, err)
155+
147156
break
148157
}
149158

150-
const msg = response.message
159+
const hostClientId = response.client_id
151160

152-
if (msg.output && !host.isVirtual) {
153-
output += msg.output
154-
}
161+
const wsURL = `${protocol}://${baseURL.host}/ws?client_id=${hostClientId}`
162+
const ws = new WebSocket(wsURL)
163+
164+
let finished = false
165+
166+
ws.on("message", (msg) => {
167+
let data
168+
try {
169+
data = JSON.parse(msg)
170+
} catch {
171+
return
172+
}
173+
174+
if (data.error === true) {
175+
err = true
176+
}
177+
178+
sendToClient(client, {
179+
success: false,
180+
error: err,
181+
message: data.message,
182+
})
183+
184+
errorClient(client, err)
185+
186+
if (data.success === true) {
187+
finished = true
188+
ws.close()
189+
} else if (err) {
190+
ws.close()
191+
}
192+
})
193+
194+
ws.on("close", () => {
195+
if (!finished && !err) {
196+
err = true
197+
198+
sendToClient(client, {
199+
error: true,
200+
message: `WoL WebSocket closed unexpectedly`,
201+
})
202+
203+
errorClient(client, err)
204+
}
205+
})
155206

156-
if (msg.success === false) {
207+
ws.on("error", () => {
157208
err = true
158-
break
159-
}
209+
210+
logger.error("Error during WebSocket connection: ", err.message)
211+
212+
sendToClient(client, {
213+
success: false,
214+
error: true,
215+
message: `WoL WebSocket error for host`,
216+
})
217+
})
218+
219+
await new Promise((resolve) => {
220+
ws.on("close", resolve)
221+
ws.on("error", resolve)
222+
})
223+
224+
if (err) break
160225
}
161226

162-
return { output, err }
227+
return { err }
163228
}
164-
165229
async function waitForHostUp(url, options = {}) {
166230
const { interval = 3000, timeout = 60000 } = options
167231
const start = Date.now()
@@ -209,9 +273,11 @@ async function startProcessing(req, res) {
209273
return res.json({ error: true, message: "No route for hostname" })
210274
}
211275

212-
const requestId = wss.createRequestId()
276+
const clientID = wss.createClientID()
213277

214-
res.json({ error: false, message: "Start request received", requestId })
278+
res.json({
279+
client_id: clientID,
280+
})
215281

216282
const { hosts, routeAttributes } = resolved
217283

@@ -221,23 +287,18 @@ async function startProcessing(req, res) {
221287

222288
let wolResult = null
223289

224-
if (wolEnabled && hosts.length > 0) {
225-
wolResult = await trySendWakeupPackets(hosts, ENV.wolURL)
226-
}
227-
228-
const ws = wss.getClient(requestId)
290+
const ws = wss.getClient(clientID)
229291

230292
if (!ws) {
231293
return
232294
}
233295

296+
if (wolEnabled && hosts.length > 0) {
297+
wolResult = await trySendWakeupPackets(ws, hosts, ENV.wolURL)
298+
}
299+
234300
if (wolResult) {
235301
err = wolResult.err
236-
237-
sendToClient(ws, {
238-
error: err,
239-
message: wolResult.output,
240-
})
241302
}
242303

243304
errorClient(ws, err)
@@ -295,7 +356,6 @@ async function startProcessing(req, res) {
295356
message: "",
296357
error: err,
297358
host: serviceURL.hostname,
298-
requestId,
299359
})
300360
}
301361

src/wss.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ function attach(server, app, router) {
1010

1111
wss.on("connection", (socket, req) => {
1212
const url = new URL(req.url, "http://localhost")
13-
const requestId = url.searchParams.get("requestId")
13+
const clientID = url.searchParams.get("client_id")
1414

15-
if (!requestId) {
16-
socket.send(JSON.stringify({ error: true, message: "Missing requestId" }))
15+
if (!clientID) {
16+
socket.send(JSON.stringify({ error: true, message: "Missing client_id" }))
1717
socket.close()
1818
return
1919
}
2020

21-
clients[requestId] = socket
21+
clients[clientID] = socket
2222

2323
socket.isAlive = true
2424

@@ -37,19 +37,19 @@ function attach(server, app, router) {
3737

3838
socket.on("close", () => {
3939
clearInterval(interval)
40-
delete clients[requestId]
40+
delete clients[clientID]
4141
})
4242
})
4343

4444
app.use("/", router)
4545
}
4646

47-
function getClient(requestId) {
48-
return clients[requestId]
47+
function getClient(clientID) {
48+
return clients[clientID]
4949
}
5050

51-
function createRequestId() {
51+
function createClientID() {
5252
return uuidv4()
5353
}
5454

55-
module.exports = { attach, getClient, createRequestId }
55+
module.exports = { attach, getClient, createClientID }

views/home.ejs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,14 @@
280280
if (!response.ok) throw new Error(`HTTP error ${response.status}`)
281281
282282
const data = await response.json()
283-
const requestId = data.requestId
284-
if (!requestId) throw new Error("No requestId returned from server")
283+
const clientID = data.client_id
284+
if (!clientID) throw new Error("No requestId returned from server")
285285
286286
logEl.textContent += "Process started. Waiting for service...\n"
287287
288288
const protocol = location.protocol === "https:" ? "wss" : "ws"
289289
const ws = new WebSocket(
290-
`${protocol}://${location.host}/ws?requestId=${requestId}`
290+
`${protocol}://${location.host}/ws?client_id=${clientID}`
291291
)
292292
293293
ws.onopen = () => {

0 commit comments

Comments
 (0)