如何使用Socket.io设置使Apache和Node.js工作?

时间:2014-01-28 16:11:54

标签: node.js apache socket.io

刚开始使用Node.js / Socket.io。最终,我希望在使用Node.js服务器推送和扩充一些内容的同时为Apache提供页面服务。这只是一个小测试,看看它是如何工作的。这是我的设置:

  • Apache 在端口 8080
  • 上运行
  • Node.js 在端口 8000
  • 上运行

将index.html页面(见下文)复制到各自的根目录。

  1. 当我打开http://localhost:8000时,一切都按预期工作,我可以看到完整的消息交换。

  2. 当我打开http://localhost:8080时,一切似乎都有效(基于请求和响应标头,Node.js日志与1比较)但我可以看到没有消息交换在Node.js或Firebug日志中。

  3. 当我第一次打开Node.js提供的页面时,关闭它,然后打开Apache所服务的页面。我可以在Node.js终端中看到“CONNECTED”,“DISCONNECTED”,然后是“CONNECTED”消息。

  4. 问题是:如何使案例 2。工作?

    页:

    <script src="http://localhost:8000/socket.io/socket.io.js"></script>
    <script>
        var socket = io.connect('http://localhost:8000');
        socket.on('server calling', function(data) {
            console.log(data);
            socket.emit('client response', {my : 'data'});
        }); 
        socket.emit('client calling', {foo : 'bar'});
    </script>
    Hello!
    

    服务器:

    var app = require('http').createServer(handler);
    var io = require('socket.io').listen(app);
    var fs = require('fs');
    
    app.listen(8000);
    
    function handler(req,res) {  
    
        path = req.url == "/" ? "./index.html" : "." + req.url; 
        fs.readFile(path,
            function(err, data) {
                if(err) {
                    res.writeHead(500);
                    return res.end('Error loading page.');
                }   
                res.writeHead(200);
                res.end(data);
            }   
        );
    
        io.sockets.on('connection', function (socket) {
    
            console.log('CONNECTED');
    
            setInterval(function() {            
                socket.emit('server calling', { hello: 'world' }); 
            }, 2000);
    
            socket.on('client response', function(data) {
                console.log(data);
            });
            socket.on('disconnect', function() {
                console.log('DISCONNECTED');
            }); 
            socket.on('client calling', function(data) {
                console.log(data);
            }); 
        });
    };
    

    我在SO上知道以下问题:

    但我仍然无法使其发挥作用......

    我试过了:

    • “将路径更改为/socket.io-client/dist/socket.io.js”

    在浏览器中: ReferenceError:未定义io 。当我转到http://localhost:8000/socket.io-client/dist/socket.io.js时,我得到欢迎来到socket.io。回复。

    在服务器日志中: info - 未处理的socket.io url

    • “从Apache静态服务器提供socket.io.js”

    那怎么办? Apache不知道如何处理/socket.io/socket.io.jsnode_modules automagic?

    • dark_ruby建议设置代理

    我将Apache根目录的index.html页面中的脚本源更改为:

    <script src="http://localhost:8080/socket.io/"></script>
    

    在Apache配置中,我添加了:

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    ProxyPass /socket.io/ http://localhost:8000/socket.io/socket.io.js
    

    使用此类配置时,http://localhost:8080的结果与 2。中的结果相同:

    $ node node-server.js
       info  - socket.io started
       debug - served static content /socket.io.js
       debug - client authorized
       info  - handshake authorized U9xPRw_0rRpsv-K9qVkS
       debug - setting request GET /socket.io/1/websocket/U9xPRw_0rRpsv-K9qVkS
       debug - set heartbeat interval for client U9xPRw_0rRpsv-K9qVkS
       debug - client authorized for 
       debug - websocket writing 1:: 
       debug - emitting heartbeat for client U9xPRw_0rRpsv-K9qVkS
       debug - websocket writing 2:: 
       debug - set heartbeat timeout for client U9xPRw_0rRpsv-K9qVkS
       debug - got heartbeat packet
       debug - cleared heartbeat timeout for client U9xPRw_0rRpsv-K9qVkS
       debug - set heartbeat interval for client U9xPRw_0rRpsv-K9qVkS
       ... 
       info  - transport end (undefined)
       debug - set close timeout for client U9xPRw_0rRpsv-K9qVkS
       debug - cleared close timeout for client U9xPRw_0rRpsv-K9qVkS
       debug - cleared heartbeat interval for client U9xPRw_0rRpsv-K9qVkS
       debug - discarding transport
    

    即。没有消息。

1 个答案:

答案 0 :(得分:5)

您的io.sockets位于处理函数内。  我假设当你向节点JS服务器发出请求时会调用它。到那时,节点JS服务器永远不会执行你的IO代码。

尝试将其移出处理程序并将其添加到app.js中。

无需更改路径或代理。你最初发布的代码就好了。问题不在于加载socket.io.js文件。但节点服务器检测到io事件。