服務器 API » 傳輸層¶
Colyseus 目前提供兩種 WebSocket 實現方案作為傳輸層使用.
每種傳輸層都有自己的一套自定義配置選項.
默認 WebSocket 傳輸層 (基於 ws
)¶
默認 WebSocket 傳輸使用 websockets/ws
實現方案.
如果沒有在 Server
的構造函數中提供 transport
參數, 則默認使用自帶的 WebSocketTransport
.
使用方法
import { Server } from "@colyseus/core";
import { WebSocketTransport } from "@colyseus/ws-transport"
const gameServer = new Server({
transport: new WebSocketTransport({ /* 配置選項 */ })
})
import Arena from "@colyseus/arena";
import { WebSocketTransport } from "@colyseus/ws-transport"
export default Arena({
// ...
initializeTransport: function() {
return new WebSocketTransport({
/* ...配置 */
});
},
// ...
});
可用配置選項:¶
options.server
:¶
一個基於 Node.js 的 http 服務器, 可供 WebSocket 服務共用. 便於讓 Express 和 Colyseus 一起使用.
import { createServer } from "http";
import { Server } from "@colyseus/core";
import { WebSocketTransport } from "@colyseus/ws-transport"
const server = createServer(); // 手動創建 http 服務器
const gameServer = new Server({
transport: new WebSocketTransport({
server // 為 `WebSocketTransport` 提供自定義服務器
})
});
import express from "express";
import { createServer } from "http";
import { Server } from "@colyseus/core";
import { WebSocketTransport } from "@colyseus/ws-transport"
const app = express();
const server = createServer(app); // 手動創建 http 服務器
const gameServer = new Server({
transport: new WebSocketTransport({
server // 為 `WebSocketTransport` 提供自定義服務器
})
});
此選項未提供的話, 默認自動創建 http 服務器.
options.pingInterval
¶
服務器 "ping" 客戶端的間隔毫秒數.
如果客戶端在 pingMaxRetries 次重試後仍然未能響應, 將被強製斷開連接.
默認: 3000
options.pingMaxRetries
¶
服務器 ping 客戶端的最大重試次數數.
默認: 2
options.verifyClient
¶
在 WebSocket 握手之前進行客戶端驗證. 如果 verifyClient
未設置,
則默認客戶端通過驗證.
-
info
(Object)origin
(String) 客戶端指定的 Origin header.req
(http.IncomingMessage) 客戶端 HTTP GET 請求.secure
(Boolean) 如果已設置req.connection.authorized
或req.connection.encrypted
則返回true
.
-
next
(Function) 用戶在info
字段檢查時必須調用的回調. 此回調中的參數為:result
(Boolean) 是否接受握手.code
(Number) 如果result
為false
, 此字段決定要發給客戶端的 HTTP 錯誤狀態代碼.name
(String) 如果result
為false
, 此字段決定要發給客戶端的 HTTP 錯誤原因.
原生 C++ WebSocket 傳輸 (協議為 uWebSockets.js
)¶
uWebSockets.js
協議通常在 CCU 數量以及內存消耗方面比默認傳輸性能更好.
HTTP 的傳輸方法與 uWebSockets.js
不同
使用 uWebSockets.js
的最大缺點在於其 HTTP/路由 的運作方式與常規 Node.js/express 不同. 了解更多信息請參考 自定義 HTTP 路由的 uWebSockets.js
安裝
npm install --save @colyseus/uwebsockets-transport
使用方法
import { Server } from "@colyseus/core";
import { uWebSocketsTransport } from "@colyseus/uwebsockets-transport"
const gameServer = new Server({
transport: new uWebSocketsTransport({
/* 選項 */
})
})
可用選項:¶
options.maxPayloadLength
¶
接收消息最大長度. 如果一個客戶端嘗試發送更大消息, 連接會立即關閉.
默認 1024 * 1024
.
options.idleTimeout
¶
消息等待最大秒數. 如果超時, 連接將關閉. 超時分辨率 (刷新粒度) 通常為 4 秒左右, 四舍五入.
使用 0
來禁用.
默認 120
.
options.compression
¶
使用何種消息壓縮方法. uWS.DISABLED
, uWS.SHARED_COMPRESSOR
或任意 uWS.DEDICATED_COMPRESSOR_xxxKB
.
默認 uWS.DISABLED
options.maxBackpressure
¶
廣播或發布消息時每個連接允許的最大背壓. 高背壓下, 速度慢的客戶端會被掠過, 直至其趕上或超時為止.
默認 1024 * 1024
.
options.key_file_name
¶
SSL 密鑰文件的路徑 (通過 Node.js 程序作用於 SSL 終端.)
options.cert_file_name
¶
SSL 證書文件的路徑 (通過 Node.js 程序作用於 SSL 終端.)
options.passphrase
¶
SSL 文件的密碼 (通過 Node.js 程序作用於 SSL 終端.)
使用 uWebSockets.js
自定義 HTTP 路由¶
原生 uWebSockets.js
傳輸:¶
uWebSocketsTransport
公開變量 app
作為 uWebSockets.js
中原生 uws.App
或 uws.SSLApp
的引用.
您可以直接使用 transport.app
來綁定原本使用 uWebSockets.js
API 的 http 傳輸功能, 如下所示:
import { uWebSocketsTransport } from "@colyseus/uwebsockets-transport"
const transport = new uWebSocketsTransport({
/* ...選項 */
});
// 異步路由
transport.app.get("/async_route", (res, req) => {
/* 沒有響應或者中斷處理的話, 不應從這裏 return 或者 yield */
res.onAborted(() => {
res.aborted = true;
});
/* 中斷程序去底層執行 C++, 此時 onAborted 函數應已被調用 */
let result = await someAsyncTask();
/* 中斷狀態下, 不應該響應 */
if (!res.aborted) {
res.writeStatus('200 OK').writeHeader('IsExample', 'Yes').end(result);
}
});
// 同步路由
transport.app.get("/sync_route", (res, req) => {
res.writeStatus('200 OK').writeHeader('IsExample', 'Yes').end('Hello there!');
});
更多詳情請參考 uWebSockets.js
示例.
另一種選擇: express 兼容層¶
作為另一種方法, 我們構建了一個輕兼容層, 旨在提供與 Express 相同的功能的同時, 使用 uWebSockets.js
作為底層.
安裝
npm install --save uwebsockets-express
使用方法
import express from "express";
import expressify from "uwebsockets-express"
import { uWebSocketsTransport } from "@colyseus/uwebsockets-transport"
const transport = new uWebSocketsTransport({
/* ...選項 */
});
const app = expressify(transport.app);
// 使用已有的中間件!
app.use(express.json());
app.use('/', serveIndex(path.join(__dirname, ".."), { icons: true, hidden: true }))
app.use('/', express.static(path.join(__dirname, "..")));
// 註冊路由
app.get("/hello", (req, res) => {
res.json({ hello: "world!" });
});
import express from "express";
import { uWebSocketsTransport } from "@colyseus/uwebsockets-transport"
import Arena from "@colyseus/arena";
export default Arena({
// ...
initializeTransport: function() {
return new uWebSocketsTransport({
/* ...選項 */
});
},
//
// 使用 `@colyseus/arena` 時, `uwebsockets-express` 被自動加載.
// 您可以通過這裏的參數獲取其引用 (transport.app).
//
initializeExpress: (app) => {
// 使用已有的中間件!
app.use('/', serveIndex(path.join(__dirname, ".."), { icons: true, hidden: true }))
app.use('/', express.static(path.join(__dirname, "..")));
// 註冊路由
app.get("/hello", (req, res) => {
res.json({ hello: "world!" });
});
},
// ...
})