我有JavaScript通过WebSocket连接在窗口上发送鼠标的坐标。
var webSocket = new WebSocket('ws:// ...');
$(window).mousemove(function (evt) {
webSocket.send(evt.pageX + ' ' + evt.pageY);
});
然后,PHP,我的后端,只是在监听这些坐标并发送给连接光标位置的每个人。
//whenever someone sends coordinates, all users connected will be notified
foreach ($webSocket->getUsers() as $user)
$user->send($xpos . ' ' . $ypos);
JavaScript获取这些数字并根据这一点移动一个红色方块。
//when PHP notifies a user, the square is updated in position
$('.square').css({
left: xpos,
top: ypos
});
最终产品如下所示:
现在的问题是它非常迟钝,但我找到了解决这个问题的方法。我为JavaScript添加了一个间隔 - 它只是每50毫秒发送一次填充数据。
setInterval(function() {
webSocket.send('filler data');
}, 50);
令人惊讶的是,这一改变让它变得更加顺畅:
我注意到左侧(鼠标移动的位置)总是如此平滑,我猜测因为左侧窗口总是发送数据,所以连接保持更顺畅而右侧窗口只接收数据。
我试过了:
$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));
输出为int(-1)
,似乎Nagle的算法仍然存在于我的应用程序中。
有点相关,Does setting TCP_NODELAY affect the behaviour of both ends of the socket?,这可能是JavaScript故意拖延数据包的问题?
答案 0 :(得分:3)
您的问题与Nagle's Algorithm有关:小数据包正在等待彼此。
禁用此设置TCP_NODELAY选项关于你的编辑,你是绝对正确的。客户端是这里的问题,因为虽然您可以在浏览器中使用javascript,但是Windows系统确实有一个注册表设置,默认情况下在tcp上启用Nagle。
答案 1 :(得分:0)
不幸的是,这是一个客户端问题。
使用注册表编辑器(Start Orb - > Run - > regedit),我们可以启用TCPNoDelay并设置TcpAckFrequency。
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\
此外,我还没有发现使用上下文更改SOCK_STREAM上的TCP_NODELAY是否可能或相关。
在目前的情况下,我刚刚决定确认(ACK)服务器发送的每个数据包。我知道这会牺牲延迟的带宽。
webSocket.onmessage = function(evt) {
webSocket.send(''); //empty, but still includes headers
dispatch(evt);
}