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 【问题描述】:我正在尝试将 nginx 与 php 应用程序和 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 错误,无法通信