Socket.io 无法在 nginx + node.js + php 应用程序中连接

Posted

技术标签:

【中文标题】Socket.io 无法在 nginx + node.js + php 应用程序中连接【英文标题】:Socket.io can't connect in nginx + node.js + php app 【发布时间】:2016-09-20 01:21:52 【问题描述】:

我正在尝试将 nginxphp 应用程序和 node.js 一起运行(这部分工作正常)。另外,我想在此设置中添加 socket.io,但不幸的是我无法在客户端和服务器之间建立连接(看起来像连接超时?)。

server.js

var app = require("http"),
    redis = require("redis"),
    io = require('socket.io')(app);


io.sockets.on( 'connection', function( client ) 
    console.log( "New client !" );

    io.sockets.emit('msg',  msg: 'Foo bar'  );
);

app.createServer().listen(3000);
console.log("Server running at 127.0.0.1:3000");

client.js

        <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<!--        <script src="/js/socket.io-client/socket.io.js" type="text/javascript"></script>-->
        <script>
            var socket = io.connect('http://localhost:3000');
            socket.on('msg', function(msg) 
                alert('News from server: ' + msg.msg);
            );
        </script>

(我尝试了许多 url 变体。有/没有 http、127.0.0.1:3000、myappp.dev 等)

这是我当前的 nginx 配置

server 
  listen                *:80;

  server_name           myapp.dev www.myapp.dev;
  client_max_body_size 1m;

  root /var/www/public;
    index  index.html index.htm index.php;

  access_log            /var/log/nginx/nxv_b3ro4tj2wiaf.access.log;
  error_log             /var/log/nginx/nxv_b3ro4tj2wiaf.error.log;
  location / 

    root  /var/www/public;
    try_files $uri $uri/ /index.php$is_args$args;
     autoindex off;
    index  index.html index.htm index.php;

    


 location ~ \.php$ 

    set $path_info $fastcgi_path_info;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    try_files $uri $uri/ /index.php$is_args$args;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;

    fastcgi_param SCRIPT_FILENAME $request_filename;

  
  sendfile off;

但我也尝试了一些其他配置,例如:

Node.js + Nginx - What now?https://www.digitalocean.com/community/questions/running-both-php-and-node-js-on-nginx-on-the-same-server

当我跑步时

DEBUG=socket.io:* nodemon --debug test.js

我明白了

[nodemon] 1.9.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node --debug test.js`
Debugger listening on port 5858
  socket.io:server initializing namespace / +0ms
Server running at 127.0.0.1:3000

没有错误,什么都没有。 知道我在做什么错吗?基本上我想做这样的事情https://github.com/jdutheil/nodePHP。但我无法让它工作。唯一的区别是来自 github 的应用程序使用的是 express 框架。我的不是。

我很确定我的服务器上的 3000 端口是开放的(顺便说一句,它是 vagrant)

编辑:

这是我的 nginx 配置。

upstream app_zendnode 
    server 127.0.0.1:3000;
    keepalive 8;


server 
  listen                *:80;

  server_name           zendnode.dev;
  client_max_body_size 1m;

  root /var/www/public;
    index  index index.html index.htm index.php;

  access_log            /var/log/nginx/zendnode.access.log;
  error_log             /var/log/nginx/zendnode.error.log;

  location / 
     root  /var/www/public;
     try_files $uri $uri/ index.php;
     autoindex on;

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;

      proxy_pass http://app_zendnode/;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

  

 location ~ \.php$ 


    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    try_files $uri $uri/ index.php /index.php$is_args$args;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;

    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param APP_ENV dev;

  
  sendfile off;

Node.js 服务器

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

var app = express();
var server = app.listen(3000);

var io = socket.listen( server )

io.sockets.on( 'connection', function( client ) 
    console.log( "New client !" );

    io.sockets.emit('msg',  msg: 'Foo bar'  );
);

Node.js 客户端

    var socket = io.connect('127.0.0.1:3000');
    socket.on('msg', function(msg) 
        alert('News from server: ' + msg.msg);
    );
    socket.on('connect', function () 
        socket.emit('hi!');
    );

现在我什至无法让 PHP 工作。我收到 404 HTTP 错误,带有文本的空白页:

Cannot GET / 

我非常喜欢这个问题Node.js + Nginx - What now?

编辑 2

这是我当前的配置。 Nginx:

upstream app_zendnode 
    server 127.0.0.1:3000;
    keepalive 8;


server 
  listen                *:80;

  server_name           zendnode.dev;
  client_max_body_size 1m;

  root /var/www/public;
    index  index index.html index.htm index.php;

  access_log            /var/log/nginx/zendnode.access.log;
  error_log             /var/log/nginx/zendnode.error.log;

  location / 
      root /var/www/public;
      try_files $uri $uri/ index.php;
      autoindex on;
  

 location /nodejsapi/ 
     root  /var/www/public;
     try_files $uri $uri/ index.php;
     autoindex on;

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;

      proxy_pass http://app_zendnode/;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

  

 location ~ \.php$ 


    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    try_files $uri $uri/ index.php /index.php$is_args$args;
    include /etc/nginx/fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;

    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_param APP_ENV dev;

  
  sendfile off;

Node.js(服务器)

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

var app = express();
var server = app.listen(3000);

var io = socket.listen( server )
io.use(monitorio( port: 8000 ));

io.sockets.on( 'connection', function( client ) 
    console.log( "New client !" );

    io.sockets.emit('msg',  msg: 'Foo bar'  );
);

客户端.js

    var socket = io.connect('127.0.0.1:3000', path: '/nodejsapi/');
    socket.on('msg', function(msg) 
        alert('News from server: ' + msg.msg);
    );
    socket.on('connect', function () 
        socket.emit('hi!');
    );

【问题讨论】:

你的socket服务器是从哪个目录运行的? 尝试使用 telnet 连接到您的 3000 端口 - 从内部和外部 vagrant 虚拟机。 【参考方案1】:

Nginx 未配置为 nodejs 的反向代理。 php 和 nodejs 请求都应该通过 nginx 上的相同端口(同源策略)。你错过了这样的东西(检查你的教程)

server 
    listen 80;
    server_name example.com;
    location / 
        proxy_pass http://APP_PRIVATE_IP_ADDRESS:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    

还有一件事。要调试此类问题,您应该使用 telnet 和 tcpdump。

在服务器上,你监听传入的连接

tcpdump -i eth0 'port 80'

在客户端,您使用

测试和发出请求
telnet mysrv.com 80

【讨论】:

我不明白。你说 PHP 和 NodeJs 应该通过同一个端口。但我无法将 node.js 设置为侦听端口 80,因为它已经被占用了。那么“请求应该通过同一个端口”是什么意思? 这意味着 nginx 应该充当代理。将端口 80 上的特定 url 模式代理到端口 3000 上的另一个 url。这称为反向代理。对于客户端,这似乎在同一个端口上。 您必须将代理绑定到特定的 url 而不是“/”。这就是为什么即使 php 也无法正常工作的原因。可以说:位置 /nodejsapi/ ... 我需要 PHP 和 Node.js 并行工作,而不仅仅是特定的 url。就像在这个例子中github.com/jdutheil/nodePHP 但是这个例子只是设计时的图片。在运行时,事物可以像这样或不同的结构。节点脚本不需要在同一个 js 文件夹下。您必须区分 URL(所有节点请求都通过 /nodejsapi/ 文件夹,所有 *.php 都通过 url *.php 结尾。这绝对没有问题。这里的主要要求是同源策略。端口必须是相同,协议和服务器地址。

以上是关于Socket.io 无法在 nginx + node.js + php 应用程序中连接的主要内容,如果未能解决你的问题,请参考以下文章

从 Nginx 到 express.js 上的 socket.io 的反向代理上的“无法获取”

使用 socket.io + nginx 时,出现 400 错误,无法通信

Nginx 在 /socket.io 请求上返回 400

带有 NGINX 和 http 2 的 Socket.io

Express、Socket.io 和 Nginx 的 CORS 问题

Socket.io SSL 连接与 Nginx 和 Express