8

我一直在使用gimite / web-socket-js来实现 WebSocket,而不仅仅是 Chrome 和 Safari 的开发版本。我想从 Ruby 服务器转移到 Node.js。突然间,它在 Chrome 之外的任何东西上都不起作用。

我怀疑这与我需要实现的Flash 套接字策略文件有关。我想将此实现为外部 Node.js 进程,以免与原始应用程序混淆。我正在使用node-websocket-server来实现带有 Node.js 的 WebSocket 协议,而且我也不想弄乱它。

似乎最简单的事情就是运行flashsocket.js,但运行它会给我以下错误:

sys:334
    ctor.prototype = Object.create(superCtor.prototype, {
                            ^
TypeError: Object prototype may only be an Object or null
    at Function.create (native)
    at Object.inherits (sys:334:29)
    at Object.<anonymous> (/Users/me/Projects/testing/websocket/node-websocket-server/flashsocket.js:10:16)
    at Module._compile (node.js:472:23)
    at Module._loadScriptSync (node.js:479:10)
    at Module.loadSync (node.js:349:12)
    at Object.runMain (node.js:532:24)
    at node.js:762:10

在这里,我们遇到了 Node.js 喜欢的可爱的神秘错误。

我的问题是是否有一个独立的全局闪存套接字策略服务器可以运行 Node.js 或其他应用程序?我的理解是我只需要让它驻留在端口 843 上。或者是否有另一个用于 Node.js 的 WebSocket 库可以像 Ruby 服务器一样处理 Flash 策略?

4

3 回答 3

8

Flash 策略请求也可以在与您提供的 WebSockets 服务相同的端口上内联响应。请参阅对 Socket.IO node.js 模块的此更改。它添加了一个连接侦听服务器,该服务器在同一端口上响应策略服务器请求。这样您就不必在端口 843 上运行某些东西(通常需要 root 权限)。

或者,您也可以使用 socat 运行一个非常简单的(2 行)策略请求服务器(假设您在 *nix 系统上):http: //github.com/kanaka/noVNC/blob/master/docs/flash_policy.txt

更新(回复@Josh K):

一个常见的误解是端口 843 是闪存策略请求的主要位置,而相同端口的请求是一个后备,并且由于超时而速度较慢。这可能是基于通常引用的 http://www.lightsphere.com/dev/articles/flash_socket_policy.html并且还因为 Adob​​e 的文档难以追踪(和阅读)。这是有关其安全策略的 Adob​​e 文档:http: //www.adobe.com/devnet/flashplayer/articles/fplayer9_security.html

实际上,端口 843 的用途与相同的端口响应有所不同。端口 843 用于元策略(站点策略)。它优先于同端口策略。管理员可以使用它来定义整个系统的闪存策略,并且可以使用它来拒绝非特权用户允许入站闪存套接字连接。这就是它位于端口 843(在特权范围内)上的原因,因此只有系统管理员才能在该端口上启动服务。

3 秒超时仅适用于与端口 843 的连接被静默丢弃的情况。它不适用于在端口 843 上运行一些其他服务或连接被拒绝(即 TCP 重置)的情况。我一直使用相同的端口,并且只运行相同的端口策略服务器没有明显的延迟。

使用 WebSocket 服务器,同端口策略响应的另一个优点是您可以更轻松地协调闪存策略和 WebSockets 握手之间的源策略配置。

于 2010-10-28T13:45:32.997 回答
6

在 Node.js 邮件列表的帮助下,我想出了以下内容:

var net = require("net"),
    domains = ["localhost:8081"];

net.createServer(
    function(socket)
    {
        socket.write("<?xml version=\"1.0\"?>\n");
        socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n");
        socket.write("<cross-domain-policy>\n");

        domains.forEach(
            function(domain)
            {
                var parts = domain.split(':');
                socket.write("<allow-access-from domain=\""+parts[0]+"\"to-ports=\""+(parts[1]||'80')+"\"/>\n");
            }
        );

        socket.write("</cross-domain-policy>\n");
        socket.end();   
    }
).listen(843);

我还为使用 Flash Sockets的 WebSockets 应用程序编写了一个(简短的)教程。

于 2010-09-03T16:41:29.250 回答
1

最好覆盖 Stream 的监听器(socket 的监听器)。否则,当您遇到以下错误时,您的服务器将崩溃:

ECONNRESET,由对等方重置连接

防止它的实施示例:

socket.setEncoding("utf8");
socket.addListener("end", function () {socket.end();});
socket.addListener("error", function (exception) {socket.end();});
socket.addListener("timeout", function () {socket.end();});
socket.addListener("close", function (had_error) {socket.end();});

参见文档:http ://nodejs.org/api.html(在“net.Stream”)

于 2010-10-07T08:27:44.980 回答