Express +句柄上的Socket.io在https上不起作用

我正在尝试使用socket.io,但是当我在服务器上运行它时,使用https,我的socket.io不起作用。

我的app.js

let express = require('express'); let path = require('path'); let favicon = require('serve-favicon'); let logger = require('morgan'); let cookieParser = require('cookie-parser'); let bodyParser = require('body-parser'); let index = require('./routes/index'); let users = require('./routes/users'); let dashboard = require('./routes/dashboard'); let app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); // uncomment after placing your favicon in /public app.use(favicon(path.join(__dirname, 'public/images', 'chatbotico.png'))); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(methodOverride('X-HTTP-Method-Override')); app.use(session({secret: 'supernova', saveUninitialized: true, resave: true})); app.use(passport.initialize()); app.use(passport.session()); // Session-persisted message middleware app.use(function(req, res, next){ let err = req.session.error, msg = req.session.notice, success = req.session.success; delete req.session.error; delete req.session.success; delete req.session.notice; if (err) res.locals.error = err; if (msg) res.locals.notice = msg; if (success) res.locals.success = success; next(); }); app.use('/', index); app.use('/users', users); app.use('/users/dashboard', dashboard); // realtime chatbot let socket = require('./config/sock'); // Socket connection socket.conn(); socket.fromClient(); // catch 404 and forward to error handler app.use(function(req, res, next) { let err = new Error('Not Found'); err.status = 404; next(err); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app; 

所以,而不是在app.js上使用socket.io,我创build了一个函数,它是从应用程序调用,并保持所有的套接字configuration

./config/sock

 let app = require('express')(); let https = require('https'); let fs = require('fs'); let options = { key: fs.readFileSync('./server.key'), cert: fs.readFileSync('./server.crt'), requestCert: false, rejectUnauthorized: false }; let server = https.createServer(options, app); let io = require('socket.io')(server); io.set("transports", ["xhr-polling","websocket","polling", "htmlfile"]); let conn = function() { server.listen(8080, function(){ }); app.get('/', function (req, res) { res.set('Content-Type', 'text/xml; charset=utf-8'); res.sendfile(__dirname + '/index.html'); }); }; let fromClient = function() { io.on('connection', function (socket) { socket.on('fromClient', function (data) { console.log(data); }); }); }); }; module.exports = {conn,fromClient}; 

所以从我的客户端来说,我已经在句柄上导入了socket.io js,在./routes/dashboard上发送了

./views/dashboard/dashboard.hbs

 <html> [...] <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> <script src="../javascripts/convo.js"></script> [...] <html> 

与此导入我尝试连接convo.js服务器端

./public/convo.js

 let socket = io.connect('https://localhost:8080', { secure: true, reconnect: true, requestCert: false, rejectUnauthorized: false }); socket.emit('fromClient', { 'client' : 'some value'}); 

我的问题是,我已经尝试了一切,使我的浏览器允许这些与自签名证书的https连接。 我不知道如何让它通过。

  localhost:8080 uses an invalid security certificate. The certificate is not trusted because it is self-signed. The certificate is not valid for the name localhost. Error code: SEC_ERROR_UNKNOWN_ISSUER 

有人能给我一个亮光。 这不是一个产品,这是一个大学项目,我不想购买证书

我已经经历了这个问题。 (浏览器真的不会再合作了,谢谢你,世界上所有愚蠢的networking犯罪分子都在为我们其他人破坏它)。

首先,编辑你的机器的主机文件来包含一个类似的条目

 lucas.example.com 127.0.0.1 

所以你可以从你自己的机器上打http://lucas.example.com:8080而不是http://localhost:8080 。 得到这个工作。 (使用你最喜欢的search引擎来弄清楚如何编辑你的主机文件。)

其次,使用lucas.example.com的通用名称创build一个自签名证书。 将该证书安装在本地计算机的Web服务器上。 点击https://lucas.example.com:8080 。 您将在浏览器中收到证书错误。 覆盖它并说服自己,你可以通过https看到本地主机。

然后弄清楚如何将自签名证书导入浏览器并告诉浏览器信任它。 这可能有帮助。 让Chrome接受自签名的本地主机证书

那么你应该能够从浏览器访问。

最后,您需要在您的机器上获得node.js来信任您的自签名证书。 这可能有帮助。 如何为HTTPS Node.js服务器使用自签名证书?

如果最坏的情况出现,你可以从namecheap.com(Comodo的经销商)购买一年的证书,价格不到10美元。 你必须certificate你拥有这个域名。

或者,也许纠缠你大学的IT部门,或让你的教授这样做。 正确的TLS证书应该是任何正确configuration的大学发展实验室的一部分。 他们应该得到*.studentlab.cs.uni.edu类的通配符证书,并让你为自己的lucas.studentlab.cs.uni.edu做这种工作。

琼斯的答案帮了我很多。 但是我改变了使用socket.io的方法

我用明确的服务器钩住了socket。

所以在app.js上,我改变了soket连接:

 // Socket connection let server = require('http').Server(app); socket.fromClient(server); 

并导出到bin / www,也是服务器variables

 module.exports = {app: app, server: server}; 

在斌/ www我已经导入的应用程序和服务器,并运行它:

 var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); var app = require('../app').app; var server = require('../app').server; /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); 

所以这允许我使用我的socket.io(在服务器端)上运行快速服务器。

 let api = require('./api'); let ipfs = require('./handlefiles'); let funct = require('./function'); let io; let fromClient = function(server) { io = require('socket.io')(server); io.on('connection', function (socket) { socket.on('fromClient', function (data) { api.getRes(data.client).then(function(res){ socket.emit('fromServer', { server: res.message, treat: res.action }); }); }); }); }; module.exports = {fromClient}; 

在客户端网站,我只是打电话localhost(或主机所需)

 let socket = io('//localhost:3000'); 

这连接服务器端的客户端,并允许我运行我的应用程序,无需在开发和生产(如服务器)的证书。