diff --git a/samples/websocket-over-http.js b/samples/websocket-over-http.js index 0698f47..1f51691 100644 --- a/samples/websocket-over-http.js +++ b/samples/websocket-over-http.js @@ -8,6 +8,12 @@ const { Publisher, } = require('@fanoutio/grip'); +const PUBLISHER = new Publisher({ + 'control_uri': 'http://localhost:5561', +}); + +const CHANNEL = 'all'; + http.createServer(async (req, res) => { // Validate the Grip-Sig header: if (!validateSig(req.headers['grip-sig'], 'changeme')) { @@ -27,6 +33,15 @@ http.createServer(async (req, res) => { return; } + let responseBody; + + // Manually set headers to accept Websocket-over-HTTP + res.setHeader('Content-Type', 'application/websocket-events'); + res.setHeader('Sec-WebSocket-Extensions', 'grip'); + + // This header causes issues with Node v20.8.1 — wscat hangs and disconnects in 5 seconds + res.removeHeader("Transfer-Encoding"); + const inEventsEncoded = await new Promise(resolve => { let body = ''; req.on('data', function (chunk) { @@ -43,30 +58,35 @@ http.createServer(async (req, res) => { if (wsContext.isOpening()) { // Open the WebSocket and subscribe it to a channel: wsContext.accept(); - wsContext.subscribe(''); + + // This adds a control messsage to output that goes to client (?) + wsContext.subscribe(CHANNEL); + // It doesn't work without it + res.setHeader('Grip-Channel', CHANNEL); // The above commands made to the wsContext are buffered // in the wsContext as "outgoing events". // Obtain them and write them to the response. const outEvents = wsContext.getOutgoingEvents(); const outEventsEncoded = encodeWebSocketEvents(outEvents); - res.write(outEventsEncoded); + responseBody = outEventsEncoded; // As an example way to check our subscription, wait and then // publish a message to the subscribed channel: setTimeout(() => { - var publisher = new Publisher({ - 'control_uri': '', - }); - publisher.publishFormats( - '', - new WebSocketMessageFormat('Test WebSocket Publish!!') - ); + PUBLISHER.publishFormats(CHANNEL, new WebSocketMessageFormat('Test WebSocket Publish!!')); }, 5000); + } else { + // Here we emulate some sort of echoing to demonstrate + // how an origin could react to incoming websocket messages + const [command, payload] = inEventsEncoded.split("\n").map(s => s.trim()); + const messageToClient = JSON.stringify({command, payload}); + PUBLISHER.publishFormats(CHANNEL, new WebSocketMessageFormat(messageToClient)); } // Set the headers required by the GRIP proxy: - res.writeHead(200, wsContext.toHeaders()); + res.writeHead(200); + if (responseBody) { res.write(responseBody) }; res.end(); }).listen(80, '0.0.0.0');