【问题标题】:Node.js + Socket.io + ApacheNode.js + Socket.io + Apache
【发布时间】:2011-12-02 16:45:32
【问题描述】:

我正在寻找一种通过以下方式集成 Node.js + Socket.io + Apache 的方法: 我希望 apache 继续提供 HTML / JS 文件。 我想让 node.js 监听端口 8080 上的连接。像这样:

var util = require("util"),
    app = require('http').createServer(handler),
    io = require('/socket.io').listen(app),
    fs = require('fs'),
    os = require('os'),
    url = require('url');

app.listen(8080);

function handler (req, res) {

    fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });

  socket.on('my other event', function (data) {
    socket.emit('ok 1', { hello: 'world' });
  });

  socket.on('clientMSG', function (data) {
    socket.emit('ok 2', { hello: 'world' });
  });

});

如果我访问连接到此服务器的 HTML,它可以工作,但我需要访问 mydomian.com:8080/index.html。 我想要的是能够访问 mydomian.com/index.html。并能够打开一个套接字连接:

<script>
        var socket = io.connect('http://mydomain.com', {port: 8080});
        socket.on('news', function (data) {
            console.log(data);
            socket.emit('my other event', { my: 'data from the client' });
        });

        socket.on('connect', function (data) {
            console.log("connect");
        });

        socket.on('disconnect', function (data) {
            console.log("disconnect");
        });


            //call this function when a button is clicked
        function sendMSG()
        {
            console.log("sendMSG"); 
            socket.emit('clientMSG', { msg: 'non-scheduled message from client' });
        }

    </script>

在这个例子中,当我转到 URL 中的 8080 端口时,我不得不使用 fs.readFile 。

有什么建议吗?谢了。

【问题讨论】:

  • 尝试使用 nginx 而不是 apache,特别是如果您只想提供静态文件。 Apache 为每个请求启动一个新线程,这部分违背了使用节点的理念/原因。

标签: javascript node.js websocket socket.io


【解决方案1】:

从 Apache 端口 80 提供静态内容,并通过端口 8080 上的 Socket.IO 服务器提供动态/数据内容。您的 Socket.IO 应用中不需要 app = require('http').createServer(handler)

Apache 80 端口 |-------------|客户|------------| Socket.IO端口8080

var io = require('socket.io').listen(8080);

io.sockets.on('connection', function (socket) {
  io.sockets.emit('this', { will: 'be received by everyone'});

  socket.on('clientMSG', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ', msg);
  });

  socket.on('disconnect', function () {
    sockets.emit('user disconnected');
  });
});

【讨论】:

  • 感谢您的回复。我做了更改,现在看起来客户端没有获取 /socket.io/socket.io.js 文件。这个文件是由 Node 中的 HTTP 服务器提供的吗?
  • 我搞定了。将路径更改为 /socket.io-client/dist/socket.io.js 谢谢!
  • 是的,您需要在端口 80 上从您的 Apache 静态服务器提供 socket.io.js 并执行类似 的操作您的客户端代码
  • idk 如果这会有所帮助,但如果你在当前目录中 npm install socket.io,在 :8888 运行应用程序,你需要编写脚本 src="mydomain:8888/socket.io/socket.io.js",即使它是在 node_modules/socket.io/lib/socket.io.js
  • 这不会触发“同源策略”违规吗? en.wikipedia.org/wiki/Same_origin_policy
【解决方案2】:

AWS + APACHE + NODEJS + SOCKET.IO + ANGULARJS

服务器端
这适用于我在端口 80 和 NodeJS 上运行 apache 的生产服务器 在端口 8000 上。通过您想要的选项更改 NodeJS 端口...

  1. 在 /var/www/html 为 NodeJS 服务器的文件创建一个名为“nodejs”的文件夹
  2. 在不同于 80 的端口上运行 Nodejs,例如端口 8000
  3. 执行命令:a2enmod proxy_http
  4. 执行命令:a2enmod proxy_wstunnel
  5. 将接下来的 2 行放在以下文件的末尾:/etc/apache2/apache2.conf

    LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
    LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so 
    
  6. 将接下来的 12 行放在以下文件的末尾:/sites-available/000-default.conf
    (如果您创建了其他网站,请将这些行放在那里)

    RewriteEngine On
    RewriteCond %{REQUEST_URI}  ^socket.io          [NC]
    RewriteCond %{QUERY_STRING} transport=websocket [NC]
    RewriteRule /{.*}       ws://localhost:8000/$1  [P,L]
    
    RewriteCond %{HTTP:Connection} Upgrade [NC]
    RewriteRule /(.*) ws://localhost:8000/$1 [P,L]
    
    ProxyPass /nodejs http://localhost:8000/
    ProxyPassReverse /nodejs http://localhost:8000/
    
    
    ProxyPass /socket.io http://localhost:8000/socket.io
    ProxyPassReverse /socket.io http://loacalhost:8000/socket.io
    
    ProxyPass /socket.io ws://localhost:8000/socket.io
    ProxyPassReverse /socket.io ws://localhost:8000/socket.io
    
  7. sudo service apache2 重启


客户端
我使用以下library 在 AngularJS 中实现 Socket.io,但是 我认为本指南
对于 socket.io 技术的基本 Javascript 实现也很有用。

调用我的 PHP 服务器:example.com
调用 NodeJS 服务器:example.com/nodejs
调用 NodeJS Socket:example.com

希望能帮到你!

【讨论】:

  • 谢谢,我能够解决在 apache 服务器上运行 socket.io 的问题。
  • 使用您的出色答案和其他研究,您可以在此处找到带有 certbot、CORS 标头和解释的完整示例(如果没有您的建议,我无法做到!):stackoverflow.com/questions/9831594/…
【解决方案3】:

您可以继续从 Apache 提供页面,但您需要在 node.js/socket.io 中启用 CORS:

index.html(由 Apache 提供)

<script src = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.js"></script>
<script>
   const socket = io("ws://your.domain.com:8080");
<script>

app.js(在 nodejs 中):(启用 CORS)

const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http, {
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    }
});

http.listen(8080);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 2012-09-19
    • 2013-03-16
    • 2015-11-30
    • 1970-01-01
    相关资源
    最近更新 更多