Open preveen-stack opened 1 month ago
sh-3.2$ cat client.js
const { Agent } = require("http")
const { createConnection } = require("net");
const WebSocket = require("ws");
const agent = new Agent({
maxSockets: 1,
keepAlive: true
});
agent.createConnection = (options) => {
let { host, port } = options;
console.log("Create connection", host, port);
let socket = createConnection(options);
return socket;
};
const ws1 = new WebSocket("ws://127.0.0.1:8080", {
agent
});
const ws2 = new WebSocket("ws://127.0.0.1:8080", {
agent
});
[ws1, ws2].forEach((ws) => {
ws.on("open", () => {
console.log("WebSocket opend: %s", ws.url);
});
ws.on("close", () => {
console.log("WebSocket closed: %s", ws.url);
});
});
sh-3.2$ cat client-2.js
const WebSocket = require("ws");
// Object to store the currently open WebSocket connections
const openConnections = {};
function createWebSocketConnection(url) {
const ws = new WebSocket(url);
// Store the WebSocket connection in the openConnections object
openConnections[url] = ws;
ws.on("open", () => {
console.log("WebSocket opened: %s", url);
});
ws.on("close", () => {
console.log("WebSocket closed: %s", url);
// Remove the WebSocket connection from openConnections object
delete openConnections[url];
});
ws.on("error", (error) => {
console.error("WebSocket error:", error);
});
return ws;
}
// Function to open a WebSocket connection to a host (with max one connection)
function openConnectionToHost(url) {
// Check if a connection is already open to the given host
if (openConnections[url]) {
console.log("Connection already open to %s", url);
return openConnections[url];
}
// If no connection exists, create a new one
const ws = createWebSocketConnection(url);
return ws;
}
// Example usage
const host = "ws://127.0.0.1:8080";
const ws1 = openConnectionToHost(host);
const ws2 = openConnectionToHost(host);
sh-3.2$ cat client-3.js
const http = require('http');
const net = require('net');
const WebSocket = require('ws');
class SingleConnectionAgent extends http.Agent {
constructor() {
super({ keepAlive: true });
this.sockets = {};
}
createSocket(options, callback) {
const key = `${options.host}:${options.port}`;
// Check if a socket already exists for the host
if (this.sockets[key]) {
const error = new Error('Connection already open to this host');
if (typeof callback === 'function') {
callback(error);
}
return;
}
// Create a new socket
const socket = net.createConnection(options);
// Store the socket in the agent's sockets object
this.sockets[key] = socket;
socket.once('close', () => {
// Remove the socket from the agent's sockets object
delete this.sockets[key];
});
if (typeof callback === 'function') {
callback(null, socket);
}
}
}
// Example usage
const agent = new SingleConnectionAgent();
const ws1 = new WebSocket("ws://127.0.0.1:8080", { });
const ws2 = new WebSocket("ws://127.0.0.1:8080", { });
sh-3.2$ node client.js
Create connection 127.0.0.1 8080
Create connection 127.0.0.1 8080
WebSocket opend: ws://127.0.0.1:8080
WebSocket opend: ws://127.0.0.1:8080
^C
sh-3.2$ node client-2.js
Connection already open to ws://127.0.0.1:8080
WebSocket opened: ws://127.0.0.1:8080
^C
sh-3.2$ node client-3.js
^C
sh-3.2$