Reputation: 10975
I have JavaScript sending the coordinates of my mouse over the window via a WebSocket connection.
var webSocket = new WebSocket('ws:// ...');
$(window).mousemove(function (evt) {
webSocket.send(evt.pageX + ' ' + evt.pageY);
});
Then, PHP, my backend, is simply listening for these coordinates and sending to everyone who is connected the position of the cursor.
//whenever someone sends coordinates, all users connected will be notified
foreach ($webSocket->getUsers() as $user)
$user->send($xpos . ' ' . $ypos);
JavaScript gets these numbers and moves a red square based on this point.
//when PHP notifies a user, the square is updated in position
$('.square').css({
left: xpos,
top: ypos
});
The end product looks like this:
Now the issue is that it's very laggy, but I've found a way to combat this. I've added a interval for the JavaScript -- which just sends filler data every 50 milliseconds.
setInterval(function() {
webSocket.send('filler data');
}, 50);
Surprisingly, the change made it much smoother:
I've noticed how the left-side (where the mouse is being moved from), is always smooth, and I'm guessing that because the left window is always sending data, the connection is being kept smoother whereas the right window is only receiving data.
I've tried:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, TCP_NODELAY, 1);
var_dump(socket_get_option($socket, SOL_SOCKET, TCP_NODELAY));
The output was int(-1)
, and it seems that Nagle's algorithm is still present in my application.
Somewhat related, Does setting TCP_NODELAY affect the behaviour of both ends of the socket?, this might be the issue of JavaScript purposely delaying the packets?
Upvotes: 3
Views: 1539
Reputation: 5599
Your issue has to do with Nagle's Algorithm: Small packets of data are waiting for each other.
to disable this set TCP_NODELAY option using socket_set_option()
Regarding your edit, you are absolutely right. The client side is the problem here, because, although you can use javascript in your browser, windows systems, for example, do have a registry setting which by default enable Nagle on tcp.
Upvotes: 4
Reputation: 10975
Unfortunately this is a client-sided issue.
Using the registry editor (Start Orb -> Run -> regedit), we can enable TCPNoDelay as well set the TcpAckFrequency.
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\
Furthermore, I have not found it possible or relevant to change TCP_NODELAY on SOCK_STREAM with contexts.
In the current situation, I have just decided to acknowledge (ACK) every packet that the server sends. I know this will be sacrificing bandwidth for latency.
webSocket.onmessage = function(evt) {
webSocket.send(''); //empty, but still includes headers
dispatch(evt);
}
Upvotes: 0