鯨落筆記whale fall notes

內明學 adhyātmavidyā(意識學 Consciousness) |原始佛教 Pre-sectarian (Original) Buddhism|道教 Daoism (Taoism)|古瑜伽 Ancient Yoga|哲學 Philosophy|靈氣 Reiki|薩滿與民間信仰 Shaman & Folk Religions|太極 Tai Chi|氣功 Qi-Gong |軟件工程 Software Engineering

聯絡方式 contact: life.is.curiosity@pm.me


Websocket Forwarding in NodeJS

What is websocket forwarding?

The web-socket protocol provides a way of creating web applications that support real‑time bidirectional communication between clients and servers.  Sometimes we need to hidden the host IP (most likely a proxy server) among the communication, Nginx also has this feature but I am going to show how does it work on my JavaScript code. Here is a example to show NGINX working as a web-socket proxy. This example uses ws, a web-socket implementation built on Node.js.

First of all, please install the nodejs and npm on your local machine.

$ sudo apt-get install nodejs npm
$ sudo yum install nodejs npm

And install a NodeJS library called ws

$ sudo npm install ws

How does it work?

Using a binance websocket API for demonstration:


const http = require("http");
const WebSocket = require("ws");
const url = require("url");
const server = http.createServer();
const wsServer = new WebSocket.Server({
  noServer: true,
  perMessageDeflate: {
    zlibDeflateOptions: {
      chunkSize: 1024,
      memLevel: 7,
      level: 3,
    },
    zlibInflateOptions: {
      chunkSize: 10 * 1024,
    },
    clientNoContextTakeover: true,
    serverNoContextTakeover: true,
    clientMaxWindowBits: 10,
    serverMaxWindowBits: 10,
    concurrencyLimit: 10,
    threshold: 10,
  },
  maxPayload: 0,
});
const wsClient = new WebSocket(
  "wss://stream.binance.com:9443/ws/!miniTicker@arr"
);
var connectionPool = {};

wsClient.on("open", function open() {});
wsClient.on("message", function incoming(data) {
  Object.keys(connectionPool).forEach(function (prop) {
    connectionPool[prop].send(data);
  });
});

wsServer.getUniqueID = function () {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + "-" + s4();
};

wsServer.on("connection", function connection(ws) {
  // add ws handle to websocket list.
  ws.id = wsServer.getUniqueID();
  connectionPool[ws.id] = ws;

  ws.on("close", function close() {
    delete connectionPool[ws.id];
    console.log(
      "[" +
        ws.id +
        "] has been disconnected, Total No of Connection pool : " +
        Object.keys(connectionPool).length
    );
  });
});

server.on("upgrade", function upgrade(request, socket, head) {
  const pathname = url.parse(request.url).pathname;

  if (pathname === "/ws/!miniTicker@arr") {
    wsServer.handleUpgrade(request, socket, head, function done(ws) {
      wsServer.emit("connection", ws, request);
    });
  } else {
    socket.destroy();
  }
});
console.log("Websocket port for ticker : 19443");
server.listen(19443);

js-websocket-forwarder/websocket-forwarder.js at master · life-is-curiosity/js-websocket-forwarder · GitHub