Jump to content

WebSocket delaying the message


invisal
 Share

Recommended Posts

I run into an annoying problem which I don't know how to solve. I don't know whether WebSocket Server delay sending the message or WebSocket delay receiving the message.

var WebSocketServer = require('ws').Server;

var wss= new WebSocketServer({
	port: 88
});

var players = {};
var playerInc = 1;

var gameLoopHandler = setInterval(function() {
	broadcast(new Date().getTime().toString());
}, 200);


wss.on('connection', function connection(ws) {
	console.log("Player ID ", playerInc, "is connected");
	
	// Add player to the player list
	var id = playerInc;
	players[id] = ws;
	playerInc++;

	// Listen when websocket disconnect
	ws.on("close", function() {
		delete players[id];
	})
});

function broadcast(message) {
	for(var key in players) {
		try {
			var p = players[key];
			p.send(message);
		} catch(ex) {
		}
	}
}

For every 200ms, I broadcast the timestamp of the server. Then, I compare the timestamp that I receive from my client side.

var ws = new WebSocket("ws://127.0.0.1:88");
ws.onmessage = function(e) {
	var now = new Date().getTime();
	var diff = now - e.data;
	console.log(e.data, now, diff);
}

I expected the different to be very low since it is operating in the same machine. But here is what I get

Capture3.PNG.f8a7543146f277f4203c4b96908

Every 500ms or 1 second, there will be a big delay. Sometimes, it takes 1 second to receive the message.

 

 
Link to comment
Share on other sites

It might be something to do with your machine and what else is running.

I've just tried it on my machine and using Chrome/Firefox/Safari as clients its rock-steady between 0-1ms, very occasionally it'll be higher for Firefox, around 30-50ms for a single tick, usually followed by ~10ms for the next tick, so, very low period of slight latency, this only happened when Firefox was starting up and I havent opened it for a while so it might be trying to check for updates or something.

I've had it running for several minutes in Chrome now and it maintains 0-1ms, even with all the other clients connecting and disconnecting (think I went up to about 10 connections), rock steady the whole time.

I had to use port 3000 as 88 isn't viable on my machine.

This was running on my Mac so there are plenty of other processes running and potentially interfering.

What set up are you using when you see the latency?

Link to comment
Share on other sites

I am running Windows 10 Home edition. Here goes my story:

  • After did some researches, I thought it was the Nagle's algorithm fault. So I went to registry editor and set TcpNoDelay to 1. It does not solve my problem.
  • I thought it might be Chrome browser. So, I downloaded Firefox and the problem is still the same.
  • I thought maybe my firewall might cause the delay. I disabled my firewall. It does not solve my problem as well.
  • Then, when I saw your post, I thought, maybe it is because of my computer. So I launch a $5 Ubuntu DigitalOcean Droplet and launch nodejs server there. It turns out there is no delay.

Now, the real question is what cause the delay on my particular machine. I have Window Defender (default anti-virus by Windows 10) and Windows 10 Home edition. One thought that come to my mind is that Home edition is not meant for running a testing server. So, Microsoft did put some delay when trying to run a server from Home edition. Second thought, maybe it is because of my anti-virus. I will update if I find the real cause.

On final note, thanks for replying my post. It is little sad that it took 2 days for moderator to approve my first post.

Link to comment
Share on other sites

I have a gameserver in node with the ws module that is creeping around 50k LoC, so I wanted to test this on my machine.

I ran it and connected and didn't see any lag whatsoever from the messages. What' you PC specs? I'm on W7, 64 bit Pro.

I am getting all 0's. Been running it for several minutes now:

4d709ef6be7fad1f518212935bf72011.png

 

 

 

The only issue that I think is the problem is you're basically iterating over every single net property inside node when you broadcast! That will kill performance on nodejs's side and put more stress on the garbage collector.

For example, use console2 and console.log(players) in your broadcast function. Look at this:

 

{ '1':
   WebSocket {
     domain: null,
     _events: { close: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     _socket:
      Socket {
        _connecting: false,
        _hadError: false,
        _handle: [Object],
        _parent: null,
        _host: null,
        _readableState: [Object],
        readable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 10,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: true,
        allowHalfOpen: true,
        destroyed: false,
        bytesRead: 0,
        _bytesDispatched: 175,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: [Object],
        _idleTimeout: -1,
        _idleNext: null,
        _idlePrev: null,
        _idleStart: 8307,
        parser: null,
        on: [Function],
        _paused: false,
        read: [Function],
        _consuming: true },
     _ultron: Ultron { id: 0, ee: [Object] },
     _closeReceived: false,
     bytesReceived: 0,
     readyState: 1,
     supports: { binary: true },
     extensions: { 'permessage-deflate': [Object] },
     protocol: undefined,
     protocolVersion: 13,
     maximumPayload: null,
     speedLimit: null,
     upgradeReq:
      IncomingMessage {
        _readableState: [Object],
        readable: true,
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined,
        socket: [Object],
        connection: [Object],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Object],
        trailers: {},
        rawTrailers: [],
        upgrade: true,
        url: '/',
        method: 'GET',
        statusCode: null,
        statusMessage: null,
        client: [Object],
        _consuming: false,
        _dumped: false,
        parser: null },
     _isServer: true,
     _receiver:
      Receiver {
        fragmentedBufferPool: [Object],
        unfragmentedBufferPool: [Object],
        extensions: [Object],
        maximumPayload: 0,
        speedLimit: 0,
        state: [Object],
        overflow: [],
        headerBuffer: <Buffer 90 c4 d7 02 00 00 00 00 00 e3>,
        expectOffset: 0,
        expectBuffer: <Buffer 90 c4>,
        expectHandler: [Function],
        currentMessage: [],
        messageHandlers: [],
        dead: false,
        processing: false,
        fragmentedFullLength: 0,
        onerror: [Function: onerror],
        ontext: [Function: ontext],
        onbinary: [Function: onbinary],
        onclose: [Function: onclose],
        onping: [Function: onping],
        onpong: [Function: onpong] },
     _sender:
      Sender {
        domain: null,
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        _socket: [Object],
        extensions: [Object],
        firstFragment: true,
        compress: false,
        messageHandlers: [],
        processing: false } } }

 

Try this new code:

 

var WebSocketServer = require('ws').Server;

var wss= new WebSocketServer({
	
	port: 9300
	 
});

players =  [];

var gameLoopHandler = setInterval(function() {
	broadcast(new Date().getTime().toString());
}, 100);


wss.on('connection', function connection(socket) {
 
	
	// Add player to the player list
	var increment = players.length;
	socket.user_id = increment;
	var temp = {
			player_id: increment,
			client: socket._sender
	}
	players.push(temp);
	
 
 
		console.log("Player ID ", players.length, "is connected");
		
	// Listen when websocket disconnect
	socket.on("close", function() {
		for(var i = 0; i < players.length; i++){
				if(players.player_id == socket.user_id){
						console.log('Player '+players.player_id+' exited.');
						players.splice(i, 1);
						break;
				}
		}
	})
});

function broadcast(message) {
    try {
	 
		for(var i = 0; i < players.length; i++){
					var player = players;
					if(player.client){
						player.client.send(message);
					}
		}
    } catch (e) {
        console.log('Broadcast Error: ' + e);
    }
}

 

If this doesn't work, I have a feeling it's something to do internally with your machine

 

Link to comment
Share on other sites

4 hours ago, invisal said:

Unbelievable, I tried a lot of thing and nothing works. Then, I closed Steam and the lag is gone. I have no idea that Steam could affect my computer such an extent.

Awww, glad you got it working! I had a similar issue (well, not really but) with Skype using port 80 .. could never figure out why my nginx wouldn't start :P.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...