Vas*_*kas 12 ssl node.js express socket.io
我正在尝试使socket.io同时工作http和https连接,但似乎我的配置它只能在其中一个上工作.
使用下面的配置选项socket.io可以通过访问我的应用程序https,但是当试图通过常规访问时http它无法连接并且我收到错误.
var app = express()
, http= require('http').createServer(app)
, https = require('https').createServer(options, app)
, io = require('socket.io').listen(https, { log: false })
Run Code Online (Sandbox Code Playgroud)
后来我有了这个
http.listen(80, serverAddress);
https.listen(443, serverAddress);
Run Code Online (Sandbox Code Playgroud)
在客户端我有这个:
<script src='/socket.io/socket.io.js'></script>
var socket = io.connect('https://<%= serverAddress %>', {secure: true, 'sync disconnect on unload' : true});
Run Code Online (Sandbox Code Playgroud)
当然,如果我分别用服务器和客户端的功能.listen和https选项切换http,.connect我会得到相反的结果.Socket.io可以通过http访问,而不是通过https访问.
怎么可能实现这个目标?我需要它主要是因为它是关于Facebook应用程序,所以它必须根据Facebook规则提供http和https连接选项.
编辑:如果它有助于解决问题,我收到的错误如下
Failed to load resource: the server responded with a status of 404 (Not Found) http://DOMAIN/socket.io/socket.io.js
Run Code Online (Sandbox Code Playgroud)
因此,我得到其他如下:
Uncaught ReferenceError: io is not defined
Run Code Online (Sandbox Code Playgroud)
a_a*_*ias 15
我相信问题在于您在服务器端和客户端上设置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);
});
Run Code Online (Sandbox Code Playgroud)
客户:
script(src='/socket.io/socket.io.js')
script.
var socket = io();
socket.on('update', function(update){
document.getElementById('update').innerHTML = update;
});
Run Code Online (Sandbox Code Playgroud)
以下是服务器的关键点:
和客户端(玉的语法,但你明白了):
在客户端上,您不需要调用io.connect().此外,我不确定你的选择.看起来你有一个拼写错误(,),我找不到任何对secure的引用:在1.0文档中为true.
可以说,HTTP和HTTPS的node.js服务器对象应该具有监听任意数量的端口和接口的能力,无论是否有SSL,但目前似乎没有实现.(除了server.listen(端口)之外,我还能通过将没有请求侦听器的第二个服务器作为"handle"参数传递给server.listen(句柄,[回调])接口来让一台服务器侦听两个端口. ,[hostname],[backlog],[callback]),但它不能与SSL /非SSL服务器混合使用.)
已经提到的stunnel解决方案当然是一个可行的选择,但如果不希望安装一个单独的软件(以避免非node.js依赖),可以在node.js中本地实现相同的隧道(假设端口80上的HTTP和端口443上的HTTPS):
var fs = require('fs');
var net = require('net');
var tls = require('tls');
var sslOptions = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem')
};
tls.createServer(sslOptions, function (cleartextStream) {
var cleartextRequest = net.connect({
port: 80,
host: '127.0.0.1'
}, function () {
cleartextStream.pipe(cleartextRequest);
cleartextRequest.pipe(cleartextStream);
});
}).listen(443);
Run Code Online (Sandbox Code Playgroud)
这与使用stunnel具有相同的效果.换句话说,它将避免需要两个单独的socket.io服务器实例,同时还使node.js"https"模块成为冗余.
我做了类似的事情,它需要两个 socket.io 实例。像这样的东西:
var express = require('express');
var oneServer = express.createServer();
var anotherServer = express.createServer();
var io = require('socket.io');
var oneIo = io.listen(oneServer);
var anotherIo = io.listen(anotherServer);
Run Code Online (Sandbox Code Playgroud)
当然,您需要为两个 socket.io 实例注入消息两次。
一个不错的选择是将 SSL 处理委托给stunnel,并在代码中忘记 SSL。
| 归档时间: |
|
| 查看次数: |
21996 次 |
| 最近记录: |