简体   繁体   English

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

[英]Apache + Symfony2 + HTTPS + Node.js + Socket.io: socket.emit not firing

I've been spending hours upon hours on this problem, but to no avail. 我花了几个小时来解决这个问题,但无济于事。

EDIT: solution found (see my answer) 编辑:找到解决方案(参见我的回答)

Project background 项目背景

I'm building a project in Symfony2 , which requires a module for uploading large files. 我正在Symfony2构建一个项目,它需要一个模块来上传大文件。 I've opted for Node.js and Socket.IO (I had to learn it from scratch, so I might be missing something basic). 我选择了Node.jsSocket.IO (我必须从头开始学习它,所以我可能会遗漏一些基本的东西)。 I'm combining these with the HTML5 File and FileReader API's to send the file in slices from the client to the server. 我将这些与HTML5文件和FileReader API结合起来,将文件从客户端发送到服务器。 Preliminary tests showed this approach working great as a standalone app, where everything was handled and served by Node.js , but integration with Apache and Symfony2 seems problematic. 初步测试表明,这种方法作为一个独立的应用程序运行良好,其中所有内容都由Node.js处理和提供,但与ApacheSymfony2集成似乎存在问题。

The application has an unsecured and secured section. 该应用程序具有不安全和安全的部分。 My goal is to use Apache on ports 80 and 443 for serving the bulk of the app built in Symfony2 , and Node.js with Socket.io on port 8080 for file uploads. 我的目标是在端口80443上使用Apache来为Symfony2内置的应用程序提供大量服务,在端口8080上使用带有Socket.io Node.js来上传文件。 The client-side page connecting to the socket will be served by Apache , but the socket will run via Node.js . 连接到套接字的客户端页面将由Apache ,但套接字将通过Node.js运行。 The upload module has to run over HTTPS, as the page resides in a secured environment with an authenticated user. 上传模块必须通过HTTPS运行,因为页面位于具有经过身份验证的用户的安全环境中。

The problem is events using socket.emit or socket.send don't seem to work. 问题是使用socket.emitsocket.send事件似乎不起作用。 Client to server, or server to client, it makes no difference. 客户端到服务器,或服务器到客户端,它没有区别。 Nothing happens and there are no errors. 什么都没发生 ,也没有错误。

The code 代码

The code shown is a simplified version of my code, without the clutter and sensitive data. 显示的代码是我的代码的简化版本,没有杂乱和敏感的数据。

Server 服务器

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");
    });
});

Client 客户

// 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 %}

So the problem is... 所以问题是......

Of course there's much more to the application than this, but this is where I'm stuck. 当然,应用程序还有更多,但这是我被困的地方。 The page loads perfectly without errors, but the emit events never fire or reach the server (except for the disconnect event). 页面加载完美且没有错误,但emit事件从不会触发或到达服务器(disconnect事件除外)。 I've tried with the message event on both client and server to check if it was a problem with only custom events, but that didn't work either. 我已尝试在客户端和服务器上使用消息事件来检查它是否只是自定义事件的问题,但这也不起作用。 I'm guessing something is blocking client-server communication (it isn't the firewall, I've checked). 我猜是阻止客户端 - 服务器通信(它不是防火墙,我已经检查过)。

I'm completely at a loss here, so please help. 我在这里完全不知所措,所以请帮忙。

EDIT: solution found (see my answer) 编辑:找到解决方案(参见我的回答)

After some painstaking debugging, I've found what was wrong with my setup. 经过一些艰苦的调试,我发现我的设置出了什么问题。 Might as well share my findings, although they are (I think) unrelated to Node.js, Socket.IO or Apache. 不妨分享我的发现,尽管它们(我认为)与Node.js,Socket.IO或Apache无关。

As I mentioned, my question had simplified code to show you my setup without clutter. 正如我所提到的,我的问题已经简化了代码,可以显示我的设置而不会出现混乱。 I was, however, setting up the client through an object, using the properties to configure the socket connection. 但是,我通过一个对象设置客户端,使用属性配置套接字连接。 Like so: 像这样:

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
}

The problem lay in the use of location as a property name. 问题在于使用location作为属性名称。 It is a reserved word in Javascript and makes for some strange behaviour in this case. 它是Javascript中的保留字,在这种情况下会产生一些奇怪的行为。 I found it strange that an object's property name can't be a reserved word, so I decided to test. 我发现奇怪的是对象的属性名称不能是保留字,所以我决定测试。 I had also noticed I was referencing the property incorrectly, I forgot to use this.location when connection to the socket. 我也注意到我正在错误地引用该属性,我忘了在连接到套接字时使用this.location So I changed it to this, just as a test. 所以我把它改成了这个,就像测试一样。

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
}

But to no avail. 但无济于事。 I was still not getting data over the socket. 我还没有通过套接字获取数据。 So the next step seemed logical in my frustration-driven debugging rage. 因此,下一步在我的沮丧驱动的调试风格中似乎是合乎逻辑的。 Changing up the property name fixed everything! 更改属性名称修复了一切!

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
}

This approach worked perfectly, I was getting loads of debug messages. 这种方法工作得很好,我收到了很多调试消息。 SUCCESS!! 成功!! Whether it is expected behaviour in Javascript to override (or whatever is happening here, "to misuse" feels like a better way of putting it to me right now) object properties if you happen to use a reserved word, I don't know. 无论是Javascript中的预期行为要覆盖(或者在这里发生什么,“滥用”感觉就像现在更好的方式将它放到我身上)如果碰巧使用保留字,我不知道对象属性。 I only know I'm steering clear of them from now on! 从现在开始,我只知道我正在转向他们!

Hope it helps anyone out there! 希望它可以帮助那里的任何人!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM