我正在客户端和我自己的手写服务器上使用Flex编写类似Comet的应用程序。
我需要能够以相当高的频率从客户端发送短的数据(例如,发送之间的数量为10毫秒)。
我还需要服务器以类似的高频率推送短数据突发。
我正在使用NetConnection.call()将数据发送到服务器,并使用URLStream(使用分块编码)将数据从服务器推送到客户端。
我发现,数据一旦可用就不会被发送/接收。例如,在IE中,似乎每200ms发送一次数据,而不是一旦调用NetConnection.call()就发送数据。同样,URLStream在服务器发送数据后也不会使数据可用。
根据浏览器之间的行为差异来判断,似乎Flash Player(版本10)依赖主机浏览器来执行所有通信。谁能证实这一点? 更新:这很可能是因为只有主机浏览器才知道可能设置的代理设置。
我尝试过使用Socket类,速度没有问题:它运行得很好。但是,我希望能够使用基于HTTP的(端口80)连接,以便我的应用程序可以在严重的防火墙环境中运行(我尝试在端口80上使用Socket,但这有问题)。
顺便说一句,所有开发/测试都是在内部局域网上完成的,因此带宽/延迟不是问题。
更新:发送/接收的数据是小包,不需要采用任何特定格式。例如,我可能需要发送一个短数组的数字,这可以在AMF中编码(例如通过NetConnection.call()),也可以放入GET参数(例如使用sendToURL())。我的问题的重点是看看是否有其他人经常遇到调用NetConnection / URLStream的相同问题,以及是否有解决方法(当然也可能是我的服务器代码,而不是Flash)
感谢。
答案 0 :(得分:1)
原来问题与Flash / Flex或任何主机浏览器无关。问题出在我的服务器代码中(在Linux上用C ++编写),如果没有访问我的源代码,很难找到原因(所以我不希望得到这个论坛的答案)。
仍然 - 谢谢所有参与其中的人。
只有在仔细查看Wireshark中显示的输出后,才注意到问题,这是双重的:
我通过多次调用write()来发送多个数据包的回复(例如,一次用于HTTP响应标头,再次用于HTTP响应主体)。服务器的TCP / IP堆栈在发送第二个数据包之前等待第一个数据包的ACK,但是由于Nagle的算法,客户端在将ACK发送回第一个数据包之前等待了200ms,因此服务器至少需要200ms来发送完整的HTTP响应。
解决方案是使用带有标志MSG_MORE的send(),直到写入所有逻辑连接的块。我也可以在TCP_CORK中使用writev()或setsockopt(),但它更适合我现有的代码使用send()。
我正在使用带有块编码的永无止境的HTTP响应来将数据推送回客户端。这里需要关闭Naggle的算法,因为即使每个块都写为一个数据包(使用MSG_MORE),客户端OS TCP / IP堆栈仍然会在发送回ACK之前等待200ms,并且服务器无法推送后续块直到获得该ACK。
这里的解决方案是要求服务器在发送下一个数据包之前不要等待每个已发送数据包的ACK,这可以通过使用TCP_NODELAY标志调用setsockopt()来完成。
上述解决方案仅适用于Linux,并且不符合POSIX标准(我认为),但对我来说这不是问题。
答案 1 :(得分:0)
我几乎100%确定玩家依靠浏览器进行此类通信。找不到这样的官方页面,但请查看this例如:
托管Flash Player的应用程序 ActiveX控件或Flash Player 插件可以使用 EnforceLocalSecurity和 DisableLocalSecurity API调用 控制安全设置。
我认为这意味着某种想法。此外,我在FF / IE上遇到了一些与网络相关的错误,这再次指出使用每个浏览器进行联网的播放器(否则不存在这样的差异)。
关于你的延迟问题,我认为如果速度至关重要,你最好的选择就是插座。你有一些工作要做,但似乎可以,再次查看docs:
SWF内容中出现此错误 调用时调度 Socket.connect()尝试连接 要么到外面的服务器 呼叫者的安全沙箱或端口 低于1024.你可以解决 通过使用跨域的问题 服务器上的策略文件。
HTH,
涓