运行 Apache 服务器中的 NodeJS

Running NodeJS in a Apache server

我正在尝试使用 Socket.IO 和 Express 制作浏览器多人游戏,尽管我不太清楚为什么需要 Express。我的服务器上有这个应用程序,在一个名为 /game 的文件夹中,因此要访问该应用程序,用户应该键入 http://www.example.com/game instead of http://www.example.com:3000,教程就是这样做的。我知道这更像是 Apache 2 VirtualHost 配置文件的问题,但我不知道 post 它在哪里。 这是我实际的 .conf 文件

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>

ServerAdmin admin@example.com
DocumentRoot /var/www/example.com/public_html
ServerName example.com
ServerAlias www.example.com
ProxyPreserveHost On
ProxyPass /game http://www.example.com:3000
ProxyPassReverse /game http://www.example.com:3000


ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

实际上,当用户输入带有端口 (http://www.example.com:3000 ), the server returns a log message like 'user connected' BUT when I enter by typing the url I want ( http://www.example.com/game) 的 url 时,它不会 returns 任何让我抓狂的消息... index.js代码:

var app = require('express')();
 var http = require('http').Server(app);
 var io = require('socket.io')(http);

 app.get('/', function(req, res){
   res.sendFile(__dirname + '/index.html');
 });

 io.on('connection', function(socket){
   console.log('a user connected');
   socket.on('disconnect', function(){
     console.log('user disconnected');
 });
 socket.on('chat message', function(msg){
    onsole.log('message: ' + msg);
 });
 });

 http.listen(3000, function(){
   console.log('listening on *:3000');
 });

index.html代码:

<!doctype html>
<html>
  <head>
    <title>Socket.IO App</title>
    <style>
     * { 
       margin: 0;
       padding: 0; 
       box-sizing: border-box; 
     }
     body { 
       font: 13px Helvetica, Arial; 
     }
     form { 
       background: #000; 
       padding: 3px; 
       position: fixed;
       bottom: 0; 
       width: 100%; 
     }
     form input { 
       border: 0; 
       padding: 10px; 
       width: 90%; 
       margin-right: .5%; 
     }
     form button { 
       width: 9%; 
       background: rgb(130, 224, 255); 
       border: none; 
       padding: 10px; 
      }
    #messages { 
       list-style-type: none; 
       margin: 0; padding: 0; 
    }
    #messages li { 
       padding: 5px 10px; 
    }
    #messages li:nth-child(odd) { 
       background: #eee; 
    }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
    $(function () {
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
      });
    });
    </script>
  </body>
</html>

提前致谢。

edit:此外,我在通过示例访问时检查了浏览器控制台。com/game 它说找不到 socket.io.js 文件,但是当以另一种方式输入时,它确实正确加载了文件...

在客户端,指定 socket.io 客户端的 path 字段:

var socket = io('http://www.example.com', {
  'path': '/game/socket.io'
});

或:

var socket = io(window.location.origin, {
  'path': window.location.pathname + '/socket.io'
});

在您的 apache 配置中,还添加 ws 重写规则以路由 websocket 流量,您将需要 proxyproxy_httpproxy_wstunnelrewrite模块:

RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /game/(.*) ws://www.example.com:3000/ [P,L]

ProxyPass        /game  http://www.example.com:3000
ProxyPassReverse /game  http://www.example.com:3000

您可以使用 docker 找到 here 示例项目来重现您的配置(节点应用程序 + apache 反向代理)