我正在尝试使用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
有人可以给我一个亮点。这不是一个产品,它是一个大学项目,我不想购买证书
答案 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');
这使客户端与服务器端挂钩并允许我运行我的应用程序而无需证书,无论是在服务器等开发和生产上。