簡體   English   中英

Apache + Symfony2 + HTTPS + Node.js + Socket.io:socket.emit沒有觸發

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

我花了幾個小時來解決這個問題,但無濟於事。

編輯:找到解決方案(參見我的回答)

項目背景

我正在Symfony2構建一個項目,它需要一個模塊來上傳大文件。 我選擇了Node.jsSocket.IO (我必須從頭開始學習它,所以我可能會遺漏一些基本的東西)。 我將這些與HTML5文件和FileReader API結合起來,將文件從客戶端發送到服務器。 初步測試表明,這種方法作為一個獨立的應用程序運行良好,其中所有內容都由Node.js處理和提供,但與ApacheSymfony2集成似乎存在問題。

該應用程序具有不安全和安全的部分。 我的目標是在端口80443上使用Apache來為Symfony2內置的應用程序提供大量服務,在端口8080上使用帶有Socket.io Node.js來上傳文件。 連接到套接字的客戶端頁面將由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事件除外)。 我已嘗試在客戶端和服務器上使用消息事件來檢查它是否只是自定義事件的問題,但這也不起作用。 我猜是阻止客戶端 - 服務器通信(它不是防火牆,我已經檢查過)。

我在這里完全不知所措,所以請幫忙。

編輯:找到解決方案(參見我的回答)

經過一些艱苦的調試,我發現我的設置出了什么問題。 不妨分享我的發現,盡管它們(我認為)與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中的預期行為要覆蓋(或者在這里發生什么,“濫用”感覺就像現在更好的方式將它放到我身上)如果碰巧使用保留字,我不知道對象屬性。 從現在開始,我只知道我正在轉向他們!

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM