无法使 socket.io 在 HTTPS 上工作
Posted
技术标签:
【中文标题】无法使 socket.io 在 HTTPS 上工作【英文标题】:Can't make socket.io work on HTTPS 【发布时间】:2018-03-27 03:59:50 【问题描述】:我正在使用简单的 socket.io 2.0.3 服务器,没有 express 或任何类似的东西来在我的 Laravel 应用程序中运行简单的聊天功能。
在我决定将网站切换到 HTTPS 之前,一切都运行良好。现在 socket.io 拒绝连接 (ERR_CONNECTION_CLOSED)。
这是我最简单的设置:
server.js:
var io = require('socket.io')(8080,
origins : //some stuff
);
html 文件
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
var socket = io(':8080');
//more stuff
我在服务器文件夹、intermediate.crt、domain.com.crt 和 domain.com.key 中有所有需要的证书文件
有人可以帮助提供最简单的示例如何在 https 上进行这项工作吗?提前致谢!
编辑:在不使用 Express 的情况下需要可能的解决方案。
【问题讨论】:
node.js, socket.io with SSL 的可能重复项在我看来,该线程应该拥有您需要的一切。 不使用 Express 有没有办法做到这一点? 仅仅在浏览器中包含客户端代码是不够的。需要有一个服务器端的 co 组件 somplace。 你不需要 express,但是一旦你有套接字运行,上面的链接会告诉你如何连接客户端。 【参考方案1】:我无法用简单的 socket.io 代码编写这个,所以我最终还是使用了 express。
如果将来有人需要,这是最简单的工作代码:
server.js
var express = require('express');
var app = module.exports = express();
var https = require('https');
var fs = require('fs');
var server = https.createServer(
key: fs.readFileSync(/*full path to your key*/),
cert: fs.readFileSync(/*full path to your cert*/),
ca: fs.readFileSync(/*full path to your intermediate cert*/),
requestCert: true,
rejectUnauthorized: false
,app);
server.listen(8080); //listen on port 8080
var io = require('socket.io').listen(server);
io.set('origins', /*your desired origins*/);
io.set('transports', ['websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling',
'polling']);
var sockets = ;
//your socket logic
在 HTML 中:
var socket = io(':8080',secure: true);
【讨论】:
在origin中我们需要设置socket的后端URL还是应用URL?【参考方案2】:重要事实:
你必须使用 https 而不是 http , 需要加载 crt 文件并创建选项对象,如示例 客户端只需要正确的地址,例如:https://YOUR_domain.com:PORT
服务器端:
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
//High definition
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
// Globals
//var MEMORY_CLEANER_INTERVAL = 5000;
//var crypto = require('crypto');
var tls = require('tls');
//dl = require('delivery');
var fs = require("fs");
var mysql = require('mysql');
var express = require("express");
var app = express();
var http = require('http');
var https = require('https');
//var mkdirp = require('mkdirp');
var path = require('path');
//var nodemailer = require('nodemailer');
//includer
function read(f) return fs.readFileSync(f).toString();
function include(f) eval.apply(global, [read(f)]);
//var BASE = require('./lib/level1_module');
//BASE.NAME = "YEap";
var pkey = fs.readFileSync('/etc/httpd/ssl/YOUR_FILE.key');
var pcert = fs.readFileSync('/etc/httpd/ssl/YOUR_FILE_com.crt')
var SERVER_PORT = 9000;
var options =
hostname: 'YOUR_PAGE.com',
port: 9000,
key: pkey,
cert: pcert,
requestCert: true,
rejectUnauthorized: false,
;
var server = https.createServer(options, app).listen(SERVER_PORT, function()
console.log("Express server listening on port " + SERVER_PORT);
);
var io = require('socket.io').listen(server);
server.listen(SERVER_PORT);
console.log('Socket server listening on port : ' , SERVER_PORT);
【讨论】:
你为什么在https服务器上调用.listen
两次?【参考方案3】:
您可以使用所有相关设置创建一个 HTTPS 服务器实例
var https = require('https');
https.createServer(options, app).listen(443);
然后简单地将其传递给构造函数:
new SocketIo(https)
【讨论】:
以上是关于无法使 socket.io 在 HTTPS 上工作的主要内容,如果未能解决你的问题,请参考以下文章
Socket.io 在 localhost 上工作,但在部署 heroku 后无法工作?
Socket.io 无法使用 nodejs 在 aws 上工作
Socket IO Node Js 和 PHP,如何使其工作?