服务器 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!" });
});
},
// ...
})