2011-07-06 94 views
123

我試圖讓我的SSL證書運行socket.io,但它不會連接。node.js,使用SSL的socket.io

我根據我的代碼關閉聊天例如:

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,這導致它失敗。

我正在測試鉻,因爲它是此應用程序的目標瀏覽器。

我很抱歉,如果這是一個簡單的問題,我是一個節點/ socket.io新手。

謝謝!

+0

您的客戶端是否嘗試連接到'wss://'前綴URI。 – kanaka

+0

不讓它到達那裏,它使請求http://domain.com/socket.io/1/?t=1309967919512然後死亡。 – Beyond

+0

你如何指定要連接的地址? 「domain.com」聽起來像是socket.io客戶端庫中的佔位符。你可以發佈你用來連接的客戶端Javascript代碼嗎? – kanaka

回答

150

爲您的初始連接使用安全的URL,即使用「https://」而不是「http://」。如果選擇了WebSocket傳輸,那麼Socket.IO應該也自動使用「wss://」(SSL)進行WebSocket連接。

更新

您也可以嘗試創建使用「安全」選項連接:

var socket = io.connect('https://localhost', {secure: true}); 
+0

我們這樣做。我們轉到https://www.thebitcoinwheel.com,它仍然會自動向http發送請求,這是socket.io代碼的問題,也是問題的關鍵。 – Beyond

+8

安全:真的做到了,謝謝kanaka! – Beyond

+1

你們救了我的命!我無法在文檔中找到這些選項。 –

25

在相同的音符,如果你的服務器支持httphttps您可以使用連接:

var socket = io.connect('//localhost'); 

to auto detect the browser scheme and connect using htt相應的p/https。當在HTTPS,傳輸將被默認地固定,如使用

var socket = io.connect('https://localhost'); 

將使用安全Web套接字連接 - wss://(該{secure: true}是冗餘的)。

有關如何使用同一節點服務器輕鬆地同時服務http和https的更多信息,請查看this answer

23

這是我設法用快遞將其設置:

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); 
+1

這是爲我工作的唯一解決方案。謝謝你節省我的時間。 –

+0

對我有好處後,與證書 – RozzA

+0

一點點的試驗和錯誤這是一個很好的解決方案 –

4

如果您的服務器認證文件不被信任,(例如,您可以用Java中的Keytool命令生成自己的密鑰庫) ,你應該添加額外的選項rejectUnauthorized

var socket = io.connect('https://localhost', {rejectUnauthorized: false}); 
4

檢查this.configuration ..

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);