Express +车把上的Socket.io在https上不起作用

时间:2017-12-01 18:15:09

标签: 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,而是创建了一个从app调用并保存所有套接字配置的函数

./配置/袜子

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上输入

./视图/仪表板/ 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上的服务器端

./公共/ 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 

有人可以给我一个亮点。这不是一个产品,它是一个大学项目,我不想购买证书

2 个答案:

答案 0 :(得分:1)

我经历过这个问题。 (浏览器真的不会再合作了。谢谢,你们所有愚蠢的网络犯罪分子都在为我们其他人毁了它。)

首先,编辑计算机的hosts文件以包含类似

的条目
0

因此您可以从自己的计算机上点击lucas.example.com 127.0.0.1 而不是http://lucas.example.com:8080。让它工作。 (使用您最喜欢的搜索引擎找出如何编辑主机文件。)

其次,使用通用名称lucas.example.com制作自签名证书。将该证书安装在本地计算机的Web服务器中。点击http://localhost: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证书应该是任何正确配置的大学开发实验室的一部分。他们应该获得https://lucas.example.com:8080之类的通配符证书,然后让你自己*.studentlab.cs.uni.edu进行这类工作。

答案 1 :(得分:0)

O. Jones回答给了我很多帮助。但是我已经改变了使用socket.io

的方法

我使用与express相同的服务器挂接套接字。

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

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

并导出到bin / www,服务器变量

module.exports = {app: app, server: server};
在bin / 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');

这使客户端与服务器端挂钩并允许我运行我的应用程序而无需证书,无论是在服务器等开发和生产上。