sails.config.sockets
這些配置選項提供了對 Socket.IO 的透明存取,Socket.IO 是由 Sails 封裝的 WebSocket/PubSub 伺服器。
屬性 | 類型 | 預設值 | 詳細資訊 |
---|---|---|---|
adapter |
'memory' |
Socket.IO 將用來傳遞訊息的佇列。可以設定為 'memory' 或 '@sailshq/socket.io-redis' 。如果指定了 '@sailshq/socket.io-redis' ,您應確保 @sailshq/socket.io-redis 在您的應用程式的依賴項中。 |
|
transports |
['websocket'] |
Sails/Socket.IO 在連接客戶端時將使用的允許傳輸策略陣列。這應始終與您的 socket 客戶端(即 sails.io.js )中的配置相符——如果您在此處更改傳輸方式,您需要在該處配置它們,反之亦然。請注意,如果您選擇修改預設傳輸方式,那麼您可能需要在生產環境中進行額外配置。(例如,如果您添加了 polling 傳輸方式,並且您的應用程式在 Nginx 等負載平衡器後面的多個伺服器上運行,那麼您將需要配置該負載平衡器以支援 TCP sticky sessions。但是,僅啟用 websocket 傳輸方式時,這應該不是開箱即用的必要操作。)有關更多提示和最佳實踐,請參閱部署 > 擴展。 |
|
onlyAllowOrigins |
undefined |
主機(以 http:// 或 https:// 開頭)陣列,僅允許來自這些主機的 sockets 連接。預設情況下(即當此值為 undefined 時),Sails/Socket.IO 將允許來自任何來源的 sockets 連接,這對於測試很有用。但在生產模式下,從 Sails v1.0 開始,框架會強制您配置此選項,以防止跨站點 WebSocket 劫持 (CSWSH) 攻擊。因此,在 config/env/production.js 或使用環境變數中,有一個傳統的位置來配置此設定。例如,如果您計劃在測試時從在生產模式下運行的本機 Node.js/Sails.js 伺服器提供網頁,您可能需要將 https://127.0.0.1:1337 添加到此陣列中。請注意,顧名思義(並且與類似的 CORS 設定 相反),僅允許列出的來源連接。另請注意,如果連接的 socket 未在其升級請求中聲明“origin”標頭(例如,非瀏覽器環境,如原生 iOS 應用程式、命令行腳本或自訂硬體),則此設定將被忽略。如果您正在使用偽瀏覽器開發平台(如 Electron、Ionic、React Native 或 Cordova/PhoneGap),則需要確定您的工具正在將什麼(如果有)“origin”標頭附加到初始 socket 連接請求。例如,Ionic、Cordova 和 PhoneGap 都將 file:// 作為其來源發送。最後,請注意,如果您想完全使用您自己的自訂實作來覆蓋此行為,您可以選擇使用 beforeConnect 設定來代替。 |
如果您正在為生產環境配置您的 Sails 應用程式,並計劃擴展到多個伺服器,那麼您應該將 sails.config.sockets.adapter
設定為 '@sailshq/socket.io-redis'
,設定您的 Redis 實例,然後使用以下配置從您的應用程式指向它
屬性 | 類型 | 預設值 | 詳細資訊 |
---|---|---|---|
url |
undefined |
要連接的 Redis 實例的連線 URL。這可能包括以下一個或多個設定,例如 redis://:[email protected]:1234/5 將指示 host 為 myredishost.com ,port 為 1234 ,pass 為 mypass ,db 為 5 。通常,您應該使用 url 或 以下設定的組合,以避免混淆(url 設定將覆蓋以下所有設定)。 |
|
db |
undefined |
要在您的 redis 實例中使用的資料庫的索引。如果指定,則必須為整數。(在大多數 Redis 設定中,這將是介於 0 到 15 之間的數字。) | |
host |
'127.0.0.1' |
您的 Redis 實例的主機名稱。 | |
pass |
undefined |
您的 Redis 實例的密碼。 | |
port |
6379 |
您的 Redis 實例的埠。 |
這些配置選項提供了對底層 Socket.IO 伺服器設定的更低層級的存取,以實現完整的自訂性。
屬性 | 類型 | 預設值 | 詳細資訊 |
---|---|---|---|
beforeConnect |
undefined |
一個函數,每次新的客戶端 socket 嘗試連接到伺服器時都會運行,可用於拒絕或允許傳入的連線。適用於調整您的生產環境以防止 DoS 攻擊,或根據特定業務的啟發法拒絕 Socket.IO 連線。有關更多資訊,請參閱下面的 beforeConnect。 | |
afterDisconnect |
undefined |
當客戶端 socket 從伺服器斷開連線時運行的函數。若要定義您自己的自訂邏輯,請指定一個類似 afterDisconnect: function (session, socket, cb) {} 的函數。 |
|
allowUpgrades |
true |
這是從 Engine.io 公開的原始配置選項。它指示是否允許 Socket.io 客戶端升級他們正在使用的傳輸方式(例如,從輪詢開始,然後升級到真正的 WebSocket 連線)。 | |
cookie |
false |
這是從 Engine.io 公開的原始配置選項。它指示包含連接的 Socket.IO 客戶端的 socket id 的 HTTP cookie 的名稱。cookie 將在回應初始 Socket.IO “握手”時設定。或者,可以設定為 false 以完全停用 cookie。請注意,sails.io.js 客戶端不依賴此 cookie,因此預設情況下會停用(設定為 false )以增強安全性。如果您直接使用 Socket.IO 並且需要重新啟用此 cookie,請記住傳統設定是 "io" 。 |
|
grant3rdPartyCookie |
true |
是否公開設定 HTTP-only session cookie 的 GET /__getcookie 路由。預設情況下,如果它偵測到即將連接到跨域伺服器,Sails socket 客戶端 (sails.io.js ) 會在開始連接之前向此端點發送 JSONP 請求。對於可能使用第三方 cookie 的使用者代理,這允許 sails.io.js 使用使用者現有的 session cookie(如果他們有)將 socket 連接到跨域 Sails 伺服器(例如,如果他們已經登入)。如果沒有這個,您從 socket 發出的虛擬請求將無法存取相同的 session,並且需要使用其他機制重新驗證。 |
|
maxHttpBufferSize |
10E7 |
這是從 Engine.io 公開的原始配置選項。它反映了輪詢時訊息中的最大位元組數或字元數,然後自動關閉 socket(以避免 DoS)。 | |
path |
/socket.io |
客戶端 sockets 應連接到伺服器上的路徑。請參閱 https://socketio.dev.org.tw/docs/server-api/#server(opts:object)。 | |
pingInterval |
25000 |
這是從 Engine.io 公開的原始配置選項。它反映了“ping 封包”之間等待的毫秒數(這或多或少是“heartbeats”的演變)。 | |
pingTimeout |
60000 |
這是從 Engine.io 公開的原始配置選項。它反映了在考慮 Socket.IO 連線關閉之前,沒有 pong 封包要等待多少毫秒。 | |
sendResponseHeaders |
true |
是否在為每個 socket 請求(例如瀏覽器中的 io.socket.get() )發起的 JWR(JSON WebSocket Response)中包含回應標頭。除非您透過請求解譯器與 Sails 通訊(例如,使用 sails.io.js 瀏覽器 SDK 進行正常呼叫),否則這不會影響直接 Socket.IO 的使用。當調整高流量應用程式以擠出更多效能時,這可能很有用,因為它可以減少總頻寬使用量。但是,從 Sails v0.10 開始,回應標頭會在可能的情況下被修剪,因此即使在極高規模的應用程式中,也幾乎不需要使用此選項。 |
|
serveClient |
false |
是否在 /socket.io/socket.io.js 上提供預設 Socket.IO 客戶端。偶爾對於進階偵錯很有用。 |
|
onRedisDisconnect |
undefined |
如果 Redis 連線中斷,Sails 可以呼叫的可選函數。適用於將您的網站置於臨時維護模式或“panic mode”(請參閱 sails-hook-panic-mode 以獲取範例)。 | |
onRedisReconnect |
undefined |
如果先前中斷的 Redis 連線恢復,Sails 可以呼叫的可選函數(請參閱上面的 onDisconnect )。 |
注意:
onRedisDisconnect
和onRedisReconnect
僅適用於 Sails 為您建立的 Redis 客戶端;如果您提供自己的 Redis 客戶端(請參閱下文),則在斷開連線或重新連線的情況下,這些函數不會自動呼叫。
beforeConnect
在開發期間,當 socket 嘗試連線時,Sails 每次都允許它(很像任何 HTTP 請求都被允許到達您的路由)。然後,在生產環境中,onlyAllowOrigins
陣列確保只有來自白名單上的基本 URL 的傳入 socket 連線才被允許連線到您的應用程式。
如果您的應用程式需要更大的彈性,作為額外的預防措施,您可以定義自己的自訂邏輯來允許或拒絕 socket 連線。若要執行此操作,請指定 beforeConnect
函數
beforeConnect: function(handshake, proceed) {
// Send back `true` to allow the socket to connect.
// (Or send back `false` to reject the attempt.)
return proceed(undefined, true);
},
請注意,如果使用了
beforeConnect
,則onlyAllowOrigins
設定將被忽略。這允許您接受來自非傳統客戶端的 socket 連線(例如,在 Electron 應用程式中),這些客戶端可能未設定origin
標頭。
當客戶端 sockets 連線到 Sails 應用程式時,預設情況下它們使用 session cookie 進行驗證(啟用 session hook)。這允許 Sails 將從 socket 發出的虛擬請求與現有的使用者 session 關聯起來,類似於正常的 HTTP 請求的工作方式。
給瀏覽器客戶端的注意事項:使用者的 session cookie 無法(並且永遠不會)從客戶端 JavaScript 存取。使用 HTTP-only cookies 對於您應用程式的安全性至關重要。
sails.io.js 客戶端通常從已透過 HTTP 提取的 HTML 頁面啟動,這表示從此類瀏覽器環境連接的 sockets 通常會自動提供有效的 session cookie。因此,一切都會正常運作,並且 req.session
將可用。
但是,在跨域 sockets 的情況下,可能會收到沒有 cookie 的連線升級請求(無論如何,對於某些傳輸方式)。在這種情況下,由於沒有識別資訊將它們與 session 連結起來,因此無法追蹤虛擬請求之間請求的使用者。sails.io.js 客戶端透過首先向 CORS+JSONP 端點發送 HTTP 請求來解決此問題,以便取得第三方 cookie。然後在開啟 socket 連線時使用此 cookie。
同樣地,如果 socket 在沒有提供 session cookie 或提供損壞的 cookie 的情況下連線,則會為其建立一個臨時的、拋棄式的 session 條目。如果提供的 session cookie 與任何已知的 session 條目不符,也會發生同樣的情況。
您還可以配置 sails.io.js 以在 連接 socket 時的 url 中,以 ?cookie
查詢參數的形式傳遞 session cookie 的覆蓋。Sails 將使用此參數而不是可能已在初始連線升級請求中發送的實際 session cookie。例如,如果您正在建構獨立的 Electron 應用程式,並且您停用了 autoConnect
以支持手動連接 socket,您可以執行以下操作
var hotSocket = io.sails.connect('https://127.0.0.1:1337?cookie=smokeybear');
預設情況下,當使用 @sailshq/socket.io-redis
adapter 時,Sails 將在背景中建立新的 Redis 客戶端。在某些情況下,您可能需要建立自己的 Redis 客戶端以用於 PubSub(通常使用 node-redis 或 ioredis 模組),並將它們提供給 Sails 以用於 PubSub。當使用 Redis Sentinel 設定時,這通常會出現,這需要客戶端使用 ioredis 等模組進行連線。以下進階配置選項允許您將已連線的 Redis 客戶端和相關配置資訊傳遞給 Sails。
屬性 | 類型 | 預設值 | 詳細資訊 |
---|---|---|---|
pubClient |
undefined |
用於在 Socket.IO 使用的通道上進行發佈的自訂 Redis 客戶端。如果未指定,Sails 將為您建立一個客戶端。 | |
subClient |
undefined |
用於訂閱 Socket.IO 使用的通道的自訂 Redis 客戶端。如果未指定,Sails 將為您建立一個客戶端。 | |
adminPubClient |
undefined |
用於在內部 Sails admin bus 上進行發佈的自訂 Redis 客戶端,這允許伺服器間通訊。如果您為 pubClient 提供客戶端,您可能也需要為此設定提供客戶端。 |
|
adminSubClient |
undefined |
用於訂閱內部 Sails admin bus 的自訂 Redis 客戶端,這允許伺服器間通訊。如果您為 subClient 提供客戶端,您可能也需要為此設定提供客戶端。 |
|
subEvent |
message |
要訂閱的 Redis 客戶端事件名稱。當使用使用 ioredis 建立的客戶端時,您可能需要將此設定為 messageBuffer 。 |
- 在舊版本的 Sails (<v0.11) 和 Socket.IO (<v1.0) 中,
beforeConnect
設定稱為authorization
。