一如既往,我一直在搜索我的手指血腥找到我的问题的答案,所以我再次向所有天才伸出手! :)
我已经使用socket.io(使用express)设置了一个Node.js服务器,它使用端口8443运行良好。它运行:)。由于我的许多客户似乎不允许端口8443上的流量,因此他们无法使用我的服务。
我想知道如何在端口443上设置Node.js ,因为使用Node-server的站点已经在使用此端口(Https)。如果我尝试在我的节点服务器上使用端口443,我会得到: warn - 出错:错误:听EACCES
我的Node-js代码的一部分:
var fs = require('fs');
var https = require('https');
var express = require('express');
var socket = require('socket.io');
var port = 8443;
var sslOptions = {
pfx: fs.readFileSync('mykey.pfx'),
passphrase: ********
};
var app = express();
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, *');
next();
});
var server = https.createServer(sslOptions, app);
var io = socket.listen(server, {
"log level" : 1,
"match origin protocol" : true,
"transports" : ['websocket', 'flashsocket'
, 'xhr-polling'
, 'jsonp-polling']
});
//No need to list all my socket events I guess
server.listen(port);
连接到我的节点服务器的客户端代码:
var socket = io.connect("https://www.*MYWEBSITE*.com", { secure: true, port: 8443});
答案 0 :(得分:5)
我想你在这里问过几个不同的问题。我会自己回答它的第一个,它应该可以解决你原来的问题,但是其他一些人提出了一些值得了解的方便的部署选项。
首先,您不需要在其自己的端口上运行socket.io服务器。您可以让socket.io服务器将自己绑定到Express应用程序。例如:
// ... require stuff
var app = express();
// ... set up your express middleware, etc
var server = https.createServer(sslOptions, app);
// attach your socket.io server to the express server
var io = require("socket.io").listen(server);
server.listen(port);
无论您如何设置节点应用程序,都值得了解如何将nginx设置为反向代理。这很好,因为你不必是root用户端口< 1024运行节点应用程序时,您可以通过虚拟主机将许多应用程序绑定到同一IP地址。
这是一个nginx服务器配置块,它将反向代理节点应用程序(并支持websockets)。
server {
listen 80;
server_name app.com www.app.com # a list of hosts for this application
access_log /var/log/nginx/access/app.log; # you'll need to create /var/log/nginx/access
error_log /var/log/nginx/error/app.log; # and you'll need to create /var/log/nginx/error
# prevents 502 bad gateway error
large_client_header_buffers 8 32k;
location / {
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_set_header Accept-Encoding "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_buffers 8 32k;
proxy_buffer_size 64k;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8000; # put the port of your node app here
proxy_redirect off;
}
}
答案 1 :(得分:2)
您得到Error: listen EACCES
因为您不能将“特权端口”(端口< 1024)用作非root用户。您可以以root用户身份运行节点进程,但不要这样做。最好让nginx
(经过测试)处理HTTPS并为您代理。
答案 2 :(得分:2)
如上所述:
您不能将两个服务绑定到同一个端口。如果IIS(或apache或其他)正在侦听端口443,则必须先将其关闭。
socket.io和你的应用程序在同一个端口上侦听。
如果要绑定到编号较小的端口(< 1024),则需要以root用户身份启动应用程序,然后降级权限,以便以最少的权限运行。这可以使用process.setuid来完成:
这个例子是用express 4和socketio 1.0制作的:
var debug = require('debug')('httpssetuid');
var app = require('../app');
var http = require('http');
var https = require('https');
var fs = require('fs');
var exec = require('child_process').exec;
var EventEmitter = require('events').EventEmitter;
var ioServer = require('socket.io');
var startupItems = [];
startupItems.httpServerReady = false;
startupItems.httpsServerReady = false;
var ee = new EventEmitter();
ee.on('ready', function(arg) {
startupItems[arg] = true;
if (startupItems.httpServerReady && startupItems.httpsServerReady) {
var id = exec('id -u ' + process.env.SUDO_UID, function(error, stdout, stderr) {
if(error || stderr) throw new Error(error || stderr);
var uid = parseInt(stdout);
process.setuid(uid);
console.log('de-escalated privileges. now running as %d', uid);
setInterval(function cb(){
var rnd = Math.random();
console.log('emitting update: %d', rnd);
io.emit('update', rnd);
}, 5000);
});
};
});
app.set('http_port', process.env.PORT || 80);
app.set('https_port', process.env.HTTPS_PORT || 443);
var httpServer = http.createServer(app);
var opts = {
pfx: fs.readFileSync('httpssetuid.pfx')
};
var httpsServer = https.createServer(opts, app);
var io = new ioServer();
httpServer.listen(app.get('http_port'), function(){
console.log('httpServer listening on port %d', app.get('http_port'));
ee.emit('ready', 'httpServerReady');
});
httpsServer.listen(app.get('https_port'), function(){
console.log('httpsServer listening on port %d', app.get('https_port'));
ee.emit('ready', 'httpsServerReady');
});
io.attach(httpServer);
io.attach(httpsServer);
io.on('connection', function(socket){
console.log('socket connected: %s', socket.id);
});
如果不能选择停止IIS,最好将其配置为节点应用程序的反向代理。