Overview

You can use this tool to test the difference between using a single websocket from the client, and alternating between using multiple at once, four in this case. The latency is  full RTT. Try loading some fresh pages on youtube or steam and the difference can often be immediately noticeable depending on how good your router is at QOS.

This 'solution' is to reduce the extreme ping spikes that can come with the complex networking required to get web sockets, particularly secure ones, to play nice. It does this by ignoring any pings that are behind schedule from other channels, due to the nature of websockets, these spikes would otherwise congest the system. This makes it operate more UDP-like but also still guarantees the packets will arrive, it's just up to you want to handle the late ones!

Note: You can still test the below webserver address using this project to test some results immediately, https://chad-wyck.itch.io/multi-websocket-w-binary . I've moved from JSON to binary with protobuf and added my necessary performance graphs with babylon.js to continue testing different game projects.

More Info

wss://chadwyck.ca/ws-server-1
ws://xx.xx.xxx.xxx:3000

Use the address bar to enter in an IP or domain address, using ws or wss. The first example may still be live depending on when you are viewing this page  It sends out pings at 20/s (your average minimum game server tick), either all through a single websocket or sequentially through multiple in multi mode. There is a code snippet at the bottom of the page for a node.js server to respond to this ping, note that your solution may be entirely different and we just need to send a 'type: "pong"' message back on the socket and return the clients timestamp, in this case I'm using a Date.now(), but at a tick rate of 20/s it should be possible to use just a byte to keep track of tick ordering between the sockets as long as you have a resync threshold once the difference is 127 or more, (over 6 seconds without a returned message from the server).

Depending on your server solution, this could drastically decrease your ping spikes, cutting your worst case max RTT latency down to half or less.

This was my case when testing a server that was behind a reverse proxy that handled the TLS handshake . (Allowing the game server to be single core and not worry about the handshake lag from clients connecting or disconnecting).

This will have NO MEASURABLE PING STABILIZATION if...
- You are connecting to your websocket directly through a ws IP address, and...
- You are on a wired internet connection with 0% packet loss and an otherwise stable ping, and...
Your router QOS is top tier and you've got spare bandwidth all the time.

Server Code

Please note that this code will not normally handle a secure websocket, but in this case the game server is behind a reverse-proxy that handles the TLS handshake.

const WebSocket = require('ws');
const fs = require('fs');
const https = require('https');
const port = 3000;
const server = new WebSocket.Server({ port });
server.on("connection", (socket) => {
  console.log("Client connected");
  socket.on("message", (message) => {
      const data = JSON.parse(message);
  if (data.type === "ping") {
    socket.send(JSON.stringify({ type: "pong", timestamp: data.timestamp }));
  }
  });
  socket.on("close", () => {
    console.log("Client disconnected");
  });
});
console.log(`WebSocket server running on port ${port}`);
StatusReleased
CategoryTool
PlatformsHTML5
AuthorChad-Wyck

Leave a comment

Log in with itch.io to leave a comment.