如何让Apache和Node.js与Socket.io设置配合工作?

12

我刚开始接触Node.js/Socket.io。最终,我想从Apache提供页面,同时使用Node.js服务器推送和增强部分内容。这只是一个小测试,看看它是如何工作的。以下是我的设置:

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

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

  1. 当我打开http://localhost:8000时,一切正常,我可以看到完整的消息交换。

  2. 当我打开http://localhost:8080时,一切似乎都正常(基于请求和响应标头以及与1.相比较的Node.js日志),但我在Node.js或Firebug日志中看不到任何消息交换

  3. 当我首先打开由Node.js提供的页面,关闭它,然后打开由Apache提供的页面,它就可以正常工作。我可以在Node.js终端中看到“ CONNECTED”,“ DISCONNECTED”,然后是“ CONNECTED”消息。

问题是:如何使情况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 is not defined。当我访问 http://localhost:8000/socket.io-client/dist/socket.io.js 时,我会收到 Welcome to socket.io. 的响应。

在服务器日志中:info - unhandled socket.io url

  • 从您的Apache静态服务器提供socket.io.js

那怎么办?Apache不知道如何处理自动化的/socket.io/socket.io.jsnode_modules吗?

  • 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:80802.中的结果相同:

$ 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

即没有消息。


尝试在Apache中设置代理,我知道Nginx可以做到,相信Apache也可以。 - dark_ruby
@dark_ruby 我已经尝试过了,但仍然没有成功。请查看更新后的问题。 - Johnny Baloney
我对Apache/socket.io的了解不够,无法回答你的问题,但你应该看一下sails.js框架,它默认包含socket.io,也许还有一些“魔法”可以帮助你解决问题。http://sailsjs.org/#! 这里是关于sockets的文档:http://sailsjs.org/#!documentation/sockets - Vadorequest
1个回答

5

您的 io.sockets 位于 handler 函数内部。我假设当您向 Node JS 服务器发出请求时,它将被调用。在此之前,Node JS 服务器不会执行您的 IO 代码。

尝试将其移出 handler 并添加到 app.js 中。

无需更改路径或代理。您最初发布的代码很好。问题不在于加载 socket.io.js 文件,而在于 Node 服务器检测 io 事件。


太好了,你发现了。这解释了一切,是的,不需要代理。顺便说一下,这正是 socket.IO how-to 介绍的做法。谢谢! - Johnny Baloney
@nightgaunt 我的io.socket代码在app.js文件中,就像你提到的那样,但我仍然在托管我的网站时遇到问题。请看一下这个链接: https://dev59.com/H-o6XIcBkEYKwwoYKQ_G - Gyanesh Gouraw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接