node.js - Express + Handlebars 上的 Socket.io 无法在 https 上运行

标签 node.js express socket.io handlebars.js

我正在尝试使用 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/

相关文章:

javascript - 具有不同参数的 eventEmitter 监听器和发射器

node.js - Axios 在特定 API 的 AWS Lambda 上总是超时

node.js - Nginx 根据用户登录提供不同的文件?

node.js - 命名事件——包罗万象还是特定的?

node.js - 无法配置 Socketio : TypeError: Object #<Server> has no method 'configure'

node.js - ExpressJs 服务器以及命令行界面

php - 如何使用 node.js 实现 websocket 服务器?

node.js - 如何使用 Express 4 渲染 Swig 模板?

javascript - 使用 if 语句条件的查询输入

security - Socket.io 安全问题