【发布时间】:2013-09-10 11:05:53
【问题描述】:
我有一个基于 Node-Webkit 的应用程序,它完成了一些繁重的 WebGL 工作(足以对高端 GPU 造成压力)、相当大量的 JS 处理,并且我在订单上发送OSC 数据约 4kb/s 的节点 dgram 模块到 scsynth 子进程来控制音频。
每 10 帧动画包含一个包中的 OSC 数据,并且音频可以很好地容忍它接收到的消息中的一些延迟或不规则性,但不是我所经历的规模。
不幸的是,我发现在调用socket.send(...) 和实际发送数据之间存在很大的延迟。似乎在某些情况下,调度程序对实际发送数据的优先级很低,以至于每个新数据包几乎无限期地停滞,然后突然以大型不受控制的突发释放,溢出scsynth 命令队列。
我无法将 udp 代码放入 WebWorker,因为 node.js 对象在该上下文中不起作用。我正在考虑尝试设置一个单独的窗口(因此,进程),仅负责将通过window.postMessage 接收到的数据转发到 UDP(反之亦然),但由于postMessage 本身也是异步的,并且另一个窗口如果它不可见,它本身可能具有低优先级,我想知道这是否可能提供很多好处。
我很确定主要问题在于 Javascript 中的工作安排,而不是流程中的其他任何地方;我认为接收端没有特别的麻烦,尽管也许可以更仔细地评估。
这是一个简短的 sn-p 显示如何设置和使用套接字(包括收集一些关于发送回调的基本统计信息)。
udp = require('dgram').createSocket('udp4');
//...
var udpStats = {lastSendDelay: 0, minSendDelay:Number.MAX_VALUE, maxSendDelay:-1, meanSendDelay:undefined};
var udpSend = function(buf) {
var t = new Date();
var wasSent = function(timeOfRequest) {
return function(err) {
if ((err)) sclog("UDP send Error: " + err);
var t2 = new Date();
var dt = t2 - timeOfRequest;
udpStats.lastSendDelay = dt;
udpStats.minSendDelay = Math.min(dt, udpStats.minSendDelay);
udpStats.maxSendDelay = Math.max(dt, udpStats.maxSendDelay);
udpStats.meanSendDelay = udpStats.meanSendDelay === undefined ? dt : (udpStats.meanSendDelay+dt)/2;
};
};
udp.send(buf, 0, buf.length, UDP_PORT, 'localhost', wasSent(t));
};
【问题讨论】:
-
如果你能提供一个可运行的案例来重现这个,我会尝试修复它。
-
谢谢。实际的项目相当大而且多毛,但我也许可以强制以更简单的方式复制它,这也有助于消除我一直假设不相关的系统部分。不知道这需要多长时间,我现在只需要为实际项目使用静态音频文件,但仍然希望架构正常工作。我尝试过将 net 模块与 tcp 一起使用,但这不起作用;也许是另一个问题的主题。
-
我刚刚意识到我在和你说话,罗杰。再次感谢您提供帮助。我关于较低级别的 socket.send 的推理是否被认为是低优先级,因此未按计划执行?
-
我不认为它被安排在低优先级。顺便说一句,你的操作系统是什么?
-
我遇到的主要问题是 Windows 7 64bit。
标签: javascript node.js sockets datagram node-webkit