node.js - 对 socket.io 使用 http 和 https

标签 node.js ssl express socket.io

我正在尝试使 socket.iohttphttps 连接上都可以工作,但似乎以我当前的配置可以只在其中一个上工作。

使用以下配置选项,它可以通过 https 访问我的应用程序,但是当尝试通过 http 访问它时,它无法连接并且我收到错误消息:

    var app = express()
  , http= require('http').createServer(app)
  , https = require('https').createServer(options, app)
  , io = require('socket.io').listen(https, { log: false })

后来我有了这个:

http.listen(80, serverAddress);
https.listen(443, serverAddress);

在客户端我有这个:

<script src='/socket.io/socket.io.js'></script>

var socket = io.connect('https://<%= serverAddress %>', {secure: true, 'sync disconnect on unload' : true});

当然,如果我在 .listen.connect 函数上使用 https 选项切换 http服务器和客户端分别我得到相反的结果,例如它可以通过http而不是https访问。

如何实现这一目标?我需要它主要是因为它是关于 Facebook 应用程序的,所以它必须根据 Facebook 的规则提供 httphttps 连接选项。

编辑:如果它有助于解决问题,我收到的错误是这样的:

Failed to load resource: the server responded with a status of 404 (Not Found) http://DOMAIN/socket.io/socket.io.js

因此,我得到了其他人,例如:

Uncaught ReferenceError: io is not defined 

最佳答案

我认为问题出在您在服务器端 在客户端设置 socket.io 的方式上。

这就是我如何让它工作的(只为你)。

服务器:

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);
});

客户:

script(src='/socket.io/socket.io.js')
script.
  var socket = io();
  socket.on('update', function(update){
    document.getElementById('update').innerHTML = update;
  });

以下是服务器的关键点:

  1. 需要socket.io,但不要调用它的listen方法(假设已经需要http和https)。相反,只需保留引用。 (var ioServer = require('socket.io'))
  2. 创建您的 http 和 https 服务器
  3. 创建一个新的 ioServer 实例
  4. 绑定(bind)您的 http 和 https 服务器 (.listen)
  5. 将 http&https 服务器实例附加到 io 实例。 (.listen 是 .attach 的别名)
  6. 设置 io 事件。

和客户端(jade 语法,但你明白了):

  1. 包含 socket.io 脚本标签
  2. 调用 io 并捕获引用
  3. 设置您的事件处理程序

在客户端上,您不需要调用 io.connect()。此外,我不确定您的选择。看起来您有一个错字 (, ,),我在 1.0 文档中找不到任何对 secure: true 的引用。

关于node.js - 对 socket.io 使用 http 和 https,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17285180/

相关文章:

node.js - http-proxy-middleware + express + node.js - 无法重定向到启用客户端证书身份验证的端点

ssl - Laravel Homestead - SSL 设置

ssl - 为 Hyperledger Fabric couchdb 启用 SSL

javascript - 快速路由器中的条件语句

javascript - 如何记录现有的 nodejs API?

node.js - 如何将socket.io共享到nodejs中的其他模块?

javascript - 当 Meteor 中的导出名称冲突时会发生什么?

javascript - 在 Node.js 中使用 forEach 循环 Promise All

node.js - 带有 Gmail "From: address"的 Nodemailer 没有改变

datetime - 如何在Sails.js或Express.js中设置本地时区