153 lines
4.5 KiB
JavaScript
153 lines
4.5 KiB
JavaScript
// % import nodejs dependencies
|
|
const WebSocket = require('ws');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// % get arguments
|
|
const args = process.argv.slice(2);
|
|
const mode = args[0] || 'custom';
|
|
const channel = args[1];
|
|
|
|
// % set nickname for twitch testing
|
|
const nick = 'justinfan' + Math.floor(Math.random() * 100000);
|
|
|
|
// % declare external websocket urls and set mode
|
|
const customUrl = channel || 'wss://echo.websocket.org';
|
|
const twitchUrl = 'wss://irc-ws.chat.twitch.tv:443';
|
|
const url = mode === 'twitch' ? twitchUrl : customUrl;
|
|
console.log(`▶ Using ${mode} endpoint: ${url}`);
|
|
|
|
// $ establish new websocket connection
|
|
const ws = new WebSocket(url);
|
|
|
|
// % configure websocket settings
|
|
let lastPingTimestamp = null;
|
|
let testCount = 0;
|
|
let logBuffer = [];
|
|
let pingTimeout = null;
|
|
|
|
// % configure logging
|
|
const logDir = path.join(__dirname, 'logs');
|
|
if (!fs.existsSync(logDir)) fs.mkdirSync(logDir, { recursive: true });
|
|
const logFile = path.join(logDir, `wslog_${mode}_${Date.now()}.txt`);
|
|
|
|
// $ push log buffer
|
|
function addLog(entry) { logBuffer.push(entry); }
|
|
|
|
// $ finalize testing script
|
|
function finalizeAndExit() {
|
|
// % clear ping timeout if exists
|
|
if (pingTimeout) clearTimeout(pingTimeout);
|
|
|
|
// ~ write log file
|
|
fs.writeFileSync(logFile, `=== WebSocket Log (${mode}) at ${new Date().toISOString()} ===\n` + logBuffer.join('\n'));
|
|
|
|
// ~ Log success to console
|
|
console.log(`\n📂 Log file created: ${logFile}`);
|
|
console.log(`✅ Program will close in 3 seconds...`);
|
|
|
|
// ~ close the tester
|
|
setTimeout(() => process.exit(0), 3000);
|
|
}
|
|
|
|
// $ activate ping requests
|
|
function scheduleTestPing() {
|
|
// ~ end script after tester ran 5 times
|
|
if (testCount >= 5) return finalizeAndExit();
|
|
|
|
// ~ set a timeout for pings of 5 seconds
|
|
pingTimeout = setTimeout(() => {
|
|
// % create last ping timestamp
|
|
lastPingTimestamp = Date.now();
|
|
|
|
// % create reference for a message
|
|
let msg;
|
|
|
|
// ~ send a websocket message to a server
|
|
if (mode === 'twitch') {
|
|
msg = 'PING :tmi.twitch.tv';
|
|
ws.send(msg);
|
|
} else {
|
|
msg = 'PING';
|
|
ws.send(msg);
|
|
}
|
|
|
|
// % create a log message
|
|
const logMsg = `${new Date().toISOString()} ➡️ Sent ${msg}`;
|
|
|
|
// ~ log in console and file
|
|
console.log(logMsg);
|
|
addLog(logMsg);
|
|
|
|
// ~ add a count of +1 to testCount variable
|
|
testCount++;
|
|
|
|
// ~ run test ping again till counter exceeds 5
|
|
scheduleTestPing();
|
|
}, 5000);
|
|
}
|
|
|
|
// $ websocket configuration when connection opens
|
|
ws.on('open', () => {
|
|
// ~ console logging of connection
|
|
console.log(`${new Date().toISOString()} ✅ Connected to ${mode}`);
|
|
|
|
// ~ configure websocket authentication to twitch
|
|
if (mode === 'twitch') {
|
|
ws.send('PASS SCHMOOPIIE');
|
|
ws.send(`NICK ${nick}`);
|
|
ws.send(`JOIN ${channel}`);
|
|
console.log(`${new Date().toISOString()} ➡️ Logged in as ${nick}, Channel: ${channel}`);
|
|
}
|
|
|
|
// ~ run test ping
|
|
scheduleTestPing();
|
|
});
|
|
|
|
// $ websocket configuration on receiving a message
|
|
ws.on('message', (data) => {
|
|
// % convert message to string and get timestamp
|
|
const msg = data.toString();
|
|
const now = new Date().toISOString();
|
|
|
|
// § check active run mode
|
|
if (mode === 'custom') {
|
|
// § check if a ping arrives
|
|
if (msg.toLowerCase().includes('ping')) {
|
|
// ~ send a pong
|
|
ws.send('PONG');
|
|
|
|
// ~ log message to console and file
|
|
const logMsg = `${now} ⬅️ Echo PING received → PONG sent`;
|
|
console.log(logMsg);
|
|
addLog(logMsg);
|
|
|
|
// ~ log receive duration to console and file
|
|
const rtt = Date.now() - lastPingTimestamp;
|
|
const rttMsg = `${now} ⬅️ PONG received (RTT: ${rtt} ms)`;
|
|
console.log(rttMsg);
|
|
addLog(rttMsg);
|
|
}
|
|
} else {
|
|
// ~ log everything on twitch mode to console and file
|
|
const logMsg = `${now} ⬅️ ${msg.trim()}`;
|
|
console.log(logMsg);
|
|
addLog(logMsg);
|
|
}
|
|
});
|
|
|
|
// $ websocket configuration on error
|
|
ws.on('error', (err) => {
|
|
// ~ log error to console and file
|
|
const msg = `${new Date().toISOString()} ❌ Error: ${err.message}`;
|
|
console.error(msg);
|
|
addLog(msg);
|
|
});
|
|
|
|
// $ websocket configuration on close
|
|
ws.on('close', () => {
|
|
// ~ log closing to console and file
|
|
const msg = `${new Date().toISOString()} ⚠️ Connection closed`;
|
|
console.log(msg);
|
|
addLog(msg);
|
|
}); |