Apache + Symfony2 + HTTPS + Node.js + Socket.io:socket.emit没有触发

时间:2013-05-14 15:50:49

标签: apache node.js symfony https socket.io

我花了几个小时来解决这个问题,但无济于事。

编辑:找到解决方案(参见我的回答)

项目背景

我正在Symfony2中构建一个项目,该项目需要一个用于上传大文件的模块。我选择Node.jsSocket.IO(我必须从头开始学习它,所以我可能会遗漏一些基本内容)。 我将这些与HTML5文件和FileReader API结合起来,将文件从客户端发送到服务器。 初步测试显示,此方法作为独立应用程序运行良好,其中所有内容均由Node.js处理和提供,但与ApacheSymfony2的集成似乎存在问题。

该应用程序具有不安全和安全的部分。我的目标是在端口Apache80上使用443来为Symfony2内置的应用提供大量服务,并使用Node.js Socket.io在端口8080上进行文件上传。连接到套接字的客户端页面将由Apache提供,但套接字将通过Node.js运行。上传模块必须通过HTTPS运行,因为页面位于具有经过身份验证的用户的安全环境中。

问题是使用socket.emitsocket.send的事件似乎不起作用。客户端到服务器,或服务器到客户端,它没有区别。 没有任何事情发生并且没有错误。

代码

显示的代码是我的代码的简化版本,没有混乱和敏感数据。

服务器

var httpsModule = require('https'),
    fs = require('fs'),
    io = require('socket.io');

var httpsOptions = 
{
    key: fs.readFileSync('path/to/key'),
    cert: fs.readFileSync('/path/to/cert'),
    passphrase: "1234lol"
}

var httpsServer = httpsModule.createServer(httpsOptions);
var ioServer = io.listen(httpsServer);

httpsServer.listen(8080);

ioServer.sockets.on('connection', function(socket)
{
    // This event gets bound, but never fires
    socket.on('NewFile', function(data)
    {
        // To make sure something is happening
        console.log(data);

        // Process the new file...
    });

    // Oddly, this one does fire
    socket.on('disconnect', function()
    {
        console.log("Disconnected");
    });
});

客户端

// This is a Twig template, so I'll give an excerpt
{% block javascripts %}
{{ parent() }}

<script type="text/javascript" src="https://my.server:8080/socket.io/socket.io.js"></script>
<script type="text/javascript">

    var socket = io.connect("my.server:8080",
                {
                    secure: true,
                    port: 8080
                });


    // Imagine this is the function initiating the file upload
    // File is an object containing metadata about the file like, filename, size, etc.
    function uploadNewFile(file)
    {
         socket.emit("NewFile", item);
    }

</script>
{% endblock %}

所以问题是......

当然,应用程序还有更多,但这是我被困住的地方。页面加载完美且没有错误,但emit事件从不会触发或到达服务器(disconnect事件除外)。我已尝试在客户端和服务器上使用消息事件来检查它是否只是自定义事件的问题,但这也不起作用。我猜是有什么阻止客户端 - 服务器通信(它不是防火墙,我已经检查过了。)

我在这里完全不知所措,所以请帮忙。

编辑:找到解决方案(参见我的回答)

1 个答案:

答案 0 :(得分:3)

经过一番艰苦的调试后,我发现我的设置出了什么问题。不妨分享我的发现,尽管它们(我认为)与Node.js,Socket.IO或Apache无关。

正如我所提到的,我的问题已经简化了代码,可以显示我的设置而不会出现混乱。但是,我通过一个对象设置客户端,使用属性配置套接字连接。像这样:

var MyProject = {};

MyProject.Uploader =
{
    location: 'my.server:8080',
    socket: io.connect(location,
            {
                secure: true,
                port: 8080,
                query: "token=blabla"
            }),
    // ...lots of extra properties and methods
}

问题在于使用location作为属性名称。它是Javascript中的保留字,在这种情况下会产生一些奇怪的行为。我发现奇怪的是对象的属性名称不能是保留字,所以我决定测试。我也注意到我正在错误地引用该属性,我忘记在连接到套接字时使用this.location。所以我把它改成了这个,就像测试一样。

var MyProject = {};

MyProject.Uploader =
{
    location: 'my.server:8080',
    socket: io.connect(this.location,
            {
                secure: true,
                port: 8080,
                query: "token=blabla"
            }),
    // ...lots of extra properties and methods
}

但无济于事。我还没有通过套接字获取数据。因此,下一步在我的沮丧驱动的调试风格中似乎是合乎逻辑的。更改属性名称修复了所有内容!

var MyProject = {};

MyProject.Uploader =
{
    socketLocation: 'my.server:8080',
    socket: io.connect(this.socketLocation,
            {
                secure: true,
                port: 8080,
                query: "token=blabla"
            }),
    // ...lots of extra properties and methods
}

这种方法运行得很好,我收到了很多调试消息。成功!! 无论是Javascript中的预期行为要覆盖(或者在这里发生什么,“滥用”感觉就像现在更好的方式将它放到我身上)对象属性如果碰巧使用保留字,我不知道。从现在开始,我只知道我正在转向他们!

希望它可以帮助那里的任何人!