Skip to content

Instantly share code, notes, and snippets.

@maanimis
Last active August 8, 2025 07:47
Show Gist options
  • Select an option

  • Save maanimis/837624e57c1c11026d518cbdacc320c8 to your computer and use it in GitHub Desktop.

Select an option

Save maanimis/837624e57c1c11026d518cbdacc320c8 to your computer and use it in GitHub Desktop.
Intercepts WebSocket connections and creates multiple connections instead of one(with Reconnect)
// ==UserScript==
// @name WebSocket Connection Multiplier+Reconnect
// @namespace http://tampermonkey.net/
// @version 3.1
// @description Intercepts WebSocket connections and creates multiple connections instead of one
// @author maanimis
// @match https://example.com/
// @icon https://www.google.com/s2/favicons?sz=64&domain=example.com
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
"use strict";
const RECONNECT_DELAY = 2000; // ms
const MAX_RECONNECT_ATTEMPTS = 5;
const MULTIPLIER = 5;
const OriginalWebSocket = window.WebSocket;
const connectionGroups = new Map();
let groupCounter = 0;
function WebSocketMultiplexer(url, protocols) {
console.log(`[WebSocket Multiplier] Intercepted connection to: ${url}`);
const groupId = ++groupCounter;
const connections = [];
const bindConnectionEvents = (conn, index) => {
conn.addEventListener("open", () => {
console.log(
`[WebSocket Multiplier] Connection ${
index + 1
}/${MULTIPLIER} opened for group ${groupId}`
);
});
conn.addEventListener("error", (event) => {
console.log(
`[WebSocket Multiplier] Connection ${
index + 1
}/${MULTIPLIER} error in group ${groupId}:`,
event
);
});
conn.addEventListener("close", (event) => {
console.log(
`[WebSocket Multiplier] Connection ${
index + 1
}/${MULTIPLIER} closed in group ${groupId}`
);
});
};
const createConnection = (index, attempt = 1) => {
try {
const conn = new OriginalWebSocket(url, protocols);
conn._groupId = groupId;
conn._connectionIndex = index;
conn._attempt = attempt;
bindConnectionEvents(conn, index);
return conn;
} catch (error) {
console.error(
`[WebSocket Multiplier] Failed to create connection ${index + 1}:`,
error
);
return null;
}
};
for (let i = 0; i < MULTIPLIER; i++) {
const conn = createConnection(i);
if (conn) connections.push(conn);
}
connectionGroups.set(groupId, connections);
const primaryConnection = connections[0];
if (!primaryConnection) {
throw new Error("Failed to create any WebSocket connections");
}
const originalSend = OriginalWebSocket.prototype.send;
const originalClose = OriginalWebSocket.prototype.close;
primaryConnection.send = function (data) {
connections.forEach((conn, index) => {
if (conn.readyState === WebSocket.OPEN) {
try {
originalSend.call(conn, data);
} catch (error) {
console.error(
`[WebSocket Multiplier] Failed to send to connection ${
index + 1
}:`,
error
);
}
} else {
console.warn(
`[WebSocket Multiplier] Connection ${index + 1} not ready (state: ${
conn.readyState
})`
);
}
});
};
primaryConnection.close = function (code, reason) {
connections.forEach((conn, index) => {
if (conn._attempt < MAX_RECONNECT_ATTEMPTS) {
console.log(
`[WebSocket Multiplier] Reconnecting connection ${
index + 1
} in ${RECONNECT_DELAY}ms...`
);
setTimeout(() => {
const newConn = createConnection(index, conn._attempt + 1);
connections[index] = newConn;
}, RECONNECT_DELAY);
} else {
console.log(
`[WebSocket Multiplier] Closing all ${connections.length} connections in group ${conn._groupId}`
);
if (
conn.readyState === WebSocket.OPEN ||
conn.readyState === WebSocket.CONNECTING
) {
try {
originalClose.call(conn, code, reason);
} catch (error) {
console.error(
`[WebSocket Multiplier] Failed to close connection ${
index + 1
}:`,
error
);
}
connectionGroups.delete(conn._groupId);
}
}
});
};
return primaryConnection;
}
Object.setPrototypeOf(
WebSocketMultiplexer.prototype,
OriginalWebSocket.prototype
);
["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach((state) => {
WebSocketMultiplexer[state] = OriginalWebSocket[state];
});
window.WebSocket = WebSocketMultiplexer;
console.log(
`[WebSocket Multiplier] Userscript loaded. Will create ${MULTIPLIER} connections for each WebSocket with reconnect support.`
);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment