узел.js, socket.io с помощью SSL
Я пытаюсь получить socket.io запуск с моим сертификатом SSL, однако, он не будет подключаться.
Я основал свой код на примере чата:
var https = require('https');
var fs = require('fs');
/**
* Bootstrap app.
*/
var sys = require('sys')
require.paths.unshift(__dirname + '/../../lib/');
/**
* Module dependencies.
*/
var express = require('express')
, stylus = require('stylus')
, nib = require('nib')
, sio = require('socket.io');
/**
* App.
*/
var privateKey = fs.readFileSync('../key').toString();
var certificate = fs.readFileSync('../crt').toString();
var ca = fs.readFileSync('../intermediate.crt').toString();
var app = express.createServer({key:privateKey,cert:certificate,ca:ca });
/**
* App configuration.
*/
...
/**
* App routes.
*/
app.get('/', function (req, res) {
res.render('index', { layout: false });
});
/**
* App listen.
*/
app.listen(443, function () {
var addr = app.address();
console.log(' app listening on http://' + addr.address + ':' + addr.port);
});
/**
* Socket.IO server (single process only)
*/
var io = sio.listen(app,{key:privateKey,cert:certificate,ca:ca});
...
Если я удалю код SSL он работает нормально, однако с ним я получаю запрос на http://domain.com/socket.io/1/?t=1309967919512
обратите внимание, что он не пытается https, что приводит к его сбою.
Я тестирую на chrome, так как это целевой браузер для этого приложение.
Я извиняюсь, если это простой вопрос, я новичок node/socket.io.
спасибо!
6 ответов:
используйте безопасный URL для вашего начального соединения, т. е. вместо "http://" используйте "https://". Если выбран транспорт WebSocket, то Socket.IO следует автоматически использовать "wss: / /" (SSL) для подключения WebSocket тоже.
обновление:
вы также можете попробовать создать соединение с помощью опции "secure":
var socket = io.connect('https://localhost', {secure: true});
вот как мне удалось настроить его с помощью express:
var fs = require( 'fs' ); var app = require('express')(); var https = require('https'); var server = https.createServer({ key: fs.readFileSync('./test_key.key'), cert: fs.readFileSync('./test_cert.crt'), ca: fs.readFileSync('./test_ca.crt'), requestCert: false, rejectUnauthorized: false },app); server.listen(8080); var io = require('socket.io').listen(server); io.sockets.on('connection',function (socket) { ... }); app.get("/", function(request, response){ ... })
Я надеюсь, что это сэкономит чье-то время.обновление : для тех, кто использует шифрование позволяет использовать этот
var server = https.createServer({ key: fs.readFileSync('privkey.pem'), cert: fs.readFileSync('fullchain.pem') },app);
на той же ноте, если ваш сервер поддерживает как
http
иhttps
вы можете подключиться с помощью:var socket = io.connect('//localhost');
до автоматическое определение схемы браузер и подключиться с помощью http/https соответственно. когда в HTTPS, транспорт будет защищен по умолчанию, как подключение с помощью
var socket = io.connect('https://localhost');
будет использовать безопасные веб-сокеты -
wss://
(the{secure: true}
является избыточным).для получения дополнительной информации о том, как легко обслуживать http и https с помощью одного и того же узла сервер проверить ответ.
Если ваш сервер сертифицированный файл не является надежным, (например, вы можете создать хранилище ключей самостоятельно с keytool команда в java), вы должны добавить дополнительную опцию rejectUnauthorized
var socket = io.connect('https://localhost', {rejectUnauthorized: false});
проверить это.конфигурация..
app = module.exports = express(); var httpsOptions = { key: fs.readFileSync('certificates/server.key'), cert: fs.readFileSync('certificates/final.crt') }; var secureServer = require('https').createServer(httpsOptions, app); io = module.exports = require('socket.io').listen(secureServer,{pingTimeout: 7000, pingInterval: 10000}); io.set("transports", ["xhr-polling","websocket","polling", "htmlfile"]); secureServer.listen(3000);
на стороне сервера:
import http from 'http'; import https from 'https'; import SocketIO, { Socket } from 'socket.io'; import fs from 'fs'; import path from 'path'; import { logger } from '../../utils'; const port: number = 3001; const server: https.Server = https.createServer( { cert: fs.readFileSync(path.resolve(__dirname, '../../../ssl/cert.pem')), key: fs.readFileSync(path.resolve(__dirname, '../../../ssl/key.pem')) }, (req: http.IncomingMessage, res: http.ServerResponse) => { logger.info(`request.url: ${req.url}`); let filePath = '.' + req.url; if (filePath === './') { filePath = path.resolve(__dirname, './index.html'); } const extname = String(path.extname(filePath)).toLowerCase(); const mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.json': 'application/json' }; const contentType = mimeTypes[extname] || 'application/octet-stream'; fs.readFile(filePath, (error: NodeJS.ErrnoException, content: Buffer) => { if (error) { res.writeHead(500); return res.end(error.message); } res.writeHead(200, { 'Content-Type': contentType }); res.end(content, 'utf-8'); }); } ); const io: SocketIO.Server = SocketIO(server); io.on('connection', (socket: Socket) => { socket.emit('news', { hello: 'world' }); socket.on('updateTemplate', data => { logger.info(data); socket.emit('updateTemplate', { random: data }); }); }); server.listen(port, () => { logger.info(`Https server is listening on https://localhost:${port}`); });
на стороне клиента:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Websocket Secure Connection</title> </head> <body> <div> <button id='btn'>Send Message</button> <ul id='messages'></ul> </div> <script src='../../../node_modules/socket.io-client/dist/socket.io.js'></script> <script> window.onload = function onload() { const socket = io('https://localhost:3001'); socket.on('news', function (data) { console.log(data); }); socket.on('updateTemplate', function onUpdateTemplate(data) { console.log(data) createMessage(JSON.stringify(data)); }); const $btn = document.getElementById('btn'); const $messages = document.getElementById('messages'); function sendMessage() { socket.emit('updateTemplate', Math.random()); } function createMessage(msg) { const $li = document.createElement('li'); $li.textContent = msg; $messages.appendChild($li); } $btn.addEventListener('click', sendMessage); } </script> </body> </html>