簡體   English   中英

如何配置Socket.io在https上的同一端口上運行?

[英]How to configure Socket.io to run on same port on https?

一如既往,我一直在搜索我的手指血腥找到我的問題的答案,所以我再次接觸你所有的天才! :)

我已經使用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});

我想你在這里問了幾個不同的問題。 我將自己回答第一個,它應該解決你原來的問題,但是其他一些人提出了一些值得了解的方便的部署選項。

首先,您不需要在它自己的端口上運行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;
    }
}

您收到Error: listen EACCES因為您不能將“特權端口”(端口<1024)用作非root用戶。 您可以以root用戶身份運行節點進程,但不要這樣做。 最好有nginx (經過測試)處理HTTPS和代理。

有關信息,請參閱http://nginx.com/blog/websocket-nginx/

如前所述:

  1. 您不能將兩個服務綁定到同一個端口。 如果IIS(或apache或其他)正在偵聽端口443,則必須先將其關閉。

  2. socket.io和你的應用程序在同一個端口上偵聽。

  3. 如果要綁定到低編號端口(<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不是一個選項,最好的辦法是將其配置為節點應用程序的反向代理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM