我正在尝试使用 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,而是创建了一个从应用程序调用它并保存所有套接字配置的函数
./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};
所以从我的客户端,我在 Handlebars 上导入了 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
有人能给我一盏灯吗?这不是产品,这是一个大学项目,我不想购买证书
最佳答案
我曾经经历过这个问题。 (浏览器真的不会再合作了。谢谢你们,世界上所有愚蠢的网络犯罪分子,为我们其他人毁了它。)
首先,编辑计算机的主机文件以包含类似的条目
lucas.example.com 127.0.0.1
这样你就可以从你自己的机器上点击http://lucas.example.com:8080
而不是http://localhost:8080
。让它发挥作用。 (使用您最喜欢的搜索引擎来了解如何编辑您的主机文件。)
其次,为自己制作一个自签名证书,通用名称为 lucas.example.com。将该证书安装在本地计算机的 Web 服务器中。点击https://lucas.example.com:8080
。您将在浏览器中收到证书错误。覆盖它并说服自己可以通过 https 看到本地主机。
然后弄清楚如何将自签名证书导入浏览器并告诉浏览器信任它。这可能会有所帮助。 Getting Chrome to accept self-signed localhost certificate
然后您应该能够从浏览器进行 wss 访问。
最后,您需要在计算机上安装 node.js 以信任您的自签名证书。这可能会有所帮助。 How do I use a self signed certificate for a HTTPS Node.js server?
如果最坏的情况发生,您可以以不到 10 美元的价格从 namecheap.com(Comodo 经销商)购买一年期证书。不过,您必须证明您拥有该域名。
或者,可能会纠缠你所在大学的 IT 部门,或者让你的教授来做这件事。适当的 TLS 证书应该是任何适当配置的大学开发实验室的一部分。他们应该获得诸如 *.studentlab.cs.uni.edu
之类的通配符证书,并让您为此创建自己的 lucas.studentlab.cs.uni.edu
工作。
关于node.js - Express + Handlebars 上的 Socket.io 无法在 https 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47599216/