2014-03-19 85 views
16

我一直試圖通過SSL運行Ratchet.io(這個問題:php ratchet websocket SSL connect?)。Ratchet + nginx + SSL/secure websocket

我的web服務器正在myhost.mobi上運行,並且我爲websocket服務「wws.myhost.mobi」創建了一個單獨的虛擬主機。

我的web套接字:

$webSock = new React\Socket\Server($loop); 
$webSock->listen(8080, '0.0.0.0'); 
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
     new Ratchet\WebSocket\WsServer(
      new Ratchet\Wamp\WampServer(
       $pusher 
      ) 
     ) 
    ), 
    $webSock 
); 

我的nginx的配置(我在nginx的1.5.8):

upstream websocketserver { 
     server localhost:8080; 
} 

server { 
    server_name wss.myapp.mobi; 

    listen 443; 
    ssl on; 
    ssl_certificate /etc/ssl/myapp-mobi-ssl.crt; 
    ssl_certificate_key /etc/ssl/myapp-mobi.key; 

    access_log /var/log/wss-access-ssl.log; 
    error_log /var/log/wss-error-ssl.log; 
    location/{ 
       proxy_pass http://websocketserver; 
       proxy_http_version 1.1; 
       proxy_set_header Upgrade $http_upgrade; 
       proxy_set_header Connection "upgrade"; 
       proxy_set_header Host $host; 

       proxy_set_header X-Real-IP $remote_addr; 
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
       proxy_set_header X-Forwarded-Proto https; 
       proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect 
       proxy_redirect off; 
     } 
} 

我的客戶端腳本:

var conn = new ab.Session('wss://wss.myapp.mobi', function(o) { 

    // ... 

}, function() { 
    console.warn('WebSocket connection closed'); 
}, { 
    skipSubprotocolCheck: true 
}); 

所以,當我在Firefox中加載頁面時,發現連接到wss://wss.myapp.mobi:8080 /的傳出連接正在懸掛(微調),並且從未完成或死亡。我在日誌中看不到任何請求到達後端的蹤跡。

我在那裏錯過了什麼?

謝謝!

編輯我已經意識到我應該連接到WSS://wss.myapp.mobi,但現在我得到「101條交換協議」的地位。

編輯2一切正在與上面的配置工作。 「101交換協議」狀態原來是一個正常的消息。問題解決了!

+3

你真的幫了我這個問題進行訪問。我無法使用Nginx中的SSL來使用websocket。 原來我缺少proxy_set_header X-Forwarded-Proto https;指令在配置 - 你的問題使我添加它。 謝謝! – Rubinsh

+0

此問題已解決(請參閱編輯),但未解釋該解決方案。 –

+0

您可以將詳細解決方案作爲答案發布嗎? –

回答

0

通過檢查問題的編輯歷史,很顯然,在這個問題的配置是正確的,temuri試圖從客戶端端口設置連接,

upstream websocketserver { 
     server localhost:8080; 
} 

但是這個代碼塊告訴nginx有一個在端口8080上運行的tcp服務器,將其表示爲websocketserver別名,但運行的服務器無法公開訪問。

檢查下面的配置,

server { 
    server_name wss.myapp.mobi; 

    listen 443; 
    ssl on; 
    ssl_certificate /etc/ssl/myapp-mobi-ssl.crt; 
    ssl_certificate_key /etc/ssl/myapp-mobi.key; 

    access_log /var/log/wss-access-ssl.log; 
    error_log /var/log/wss-error-ssl.log; 
    location/{ 
       proxy_pass http://websocketserver; 
       proxy_http_version 1.1; 
       proxy_set_header Upgrade $http_upgrade; 
       proxy_set_header Connection "upgrade"; 
       proxy_set_header Host $host; 

       proxy_set_header X-Real-IP $remote_addr; 
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
       proxy_set_header X-Forwarded-Proto https; 
       proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect 
       proxy_redirect off; 
     } 
} 

此配置結合域wss.myapp.mobi到443端口啓用SSL和proxy通過proxy_pass指令荷蘭國際集團的要求向當地的WebSocket服務器,其餘的指令是用於連接升級處理。

所以WebSocket的服務器可以從瀏覽器客戶端與

// connect through binded domain 
// instead of wss.myapp.mobi:8080 which will not work 
var url = 'wss://wss.myapp.mobi';