@colyseus/uwebsockets-transport 0.16.4 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js
CHANGED
|
@@ -15,12 +15,12 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
return to;
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
var
|
|
19
|
-
__export(
|
|
18
|
+
var src_exports = {};
|
|
19
|
+
__export(src_exports, {
|
|
20
20
|
uWebSocketClient: () => import_uWebSocketClient.uWebSocketClient,
|
|
21
21
|
uWebSocketsTransport: () => import_uWebSocketsTransport.uWebSocketsTransport
|
|
22
22
|
});
|
|
23
|
-
module.exports = __toCommonJS(
|
|
23
|
+
module.exports = __toCommonJS(src_exports);
|
|
24
24
|
var import_uWebSocketClient = require("./uWebSocketClient.js");
|
|
25
25
|
var import_uWebSocketsTransport = require("./uWebSocketsTransport.js");
|
|
26
26
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -125,7 +125,7 @@ class uWebSocketsTransport extends import_core.Transport {
|
|
|
125
125
|
const originalRawSend = this._originalRawSend;
|
|
126
126
|
import_uWebSocketClient.uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function(...args) {
|
|
127
127
|
let [buf, ...rest] = args;
|
|
128
|
-
buf =
|
|
128
|
+
buf = Buffer.from(buf);
|
|
129
129
|
setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);
|
|
130
130
|
};
|
|
131
131
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/uWebSocketsTransport.ts"],
|
|
4
|
-
"sourcesContent": ["import http, { IncomingHttpHeaders } from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\nimport expressify, { Application } from \"uwebsockets-express\";\n\nimport { AuthContext, HttpServerMock, ErrorCode, matchMaker, getBearerToken, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient.js';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior<any>, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket<any> & {\n url: string,\n query: string,\n context: AuthContext,\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n public expressApp: Application;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n private _originalRawSend: typeof uWebSocketClient.prototype.raw | null = null;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n this.expressApp = expressify(this.app);\n\n if (options.maxBackpressure === undefined) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (options.compression === undefined) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (options.maxPayloadLength === undefined) {\n options.maxPayloadLength = 4 * 1024;\n }\n\n if (options.sendPingsAutomatically === undefined) {\n options.sendPingsAutomatically = true;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n // @ts-ignore\n this.server = new HttpServerMock();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n context: {\n token: getBearerToken(req.getHeader('authorization')),\n headers,\n ip: Buffer.from(res.getRemoteAddressAsText()).toString(),\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'message' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const callback = (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n // @ts-ignore\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n };\n\n if (typeof(port) === \"string\") {\n // @ts-ignore\n this.app.listen_unix(callback, port);\n\n } else {\n this.app.listen(port, callback);\n\n }\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = uWebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function (...args: any[]) {\n // copy buffer\n let [buf, ...rest] = args;\n buf = Array.from(buf);\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient.context);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => client.leave());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.cork(() => {\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n });\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n\n // @ts-ignore\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return res.close();\n }\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // cache all headers\n const headers: IncomingHttpHeaders = {};\n req.forEach((key, value) => headers[key] = value);\n\n const token = getBearerToken(headers['authorization']);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token,\n headers,\n ip: headers['x-real-ip'] ?? Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n );\n\n if (!res.aborted) {\n res.cork(() => {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n });\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import http, { IncomingHttpHeaders } from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\nimport expressify, { Application } from \"uwebsockets-express\";\n\nimport { AuthContext, HttpServerMock, ErrorCode, matchMaker, getBearerToken, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient.js';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior<any>, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket<any> & {\n url: string,\n query: string,\n context: AuthContext,\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n public expressApp: Application;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n private _originalRawSend: typeof uWebSocketClient.prototype.raw | null = null;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n this.expressApp = expressify(this.app);\n\n if (options.maxBackpressure === undefined) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (options.compression === undefined) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (options.maxPayloadLength === undefined) {\n options.maxPayloadLength = 4 * 1024;\n }\n\n if (options.sendPingsAutomatically === undefined) {\n options.sendPingsAutomatically = true;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n // @ts-ignore\n this.server = new HttpServerMock();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n context: {\n token: getBearerToken(req.getHeader('authorization')),\n headers,\n ip: Buffer.from(res.getRemoteAddressAsText()).toString(),\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'message' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const callback = (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n // @ts-ignore\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n };\n\n if (typeof(port) === \"string\") {\n // @ts-ignore\n this.app.listen_unix(callback, port);\n\n } else {\n this.app.listen(port, callback);\n\n }\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = uWebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function (...args: any[]) {\n // copy buffer\n let [buf, ...rest] = args;\n buf = Buffer.from(buf);\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient.context);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => client.leave());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.cork(() => {\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n });\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n\n // @ts-ignore\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return res.close();\n }\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // cache all headers\n const headers: IncomingHttpHeaders = {};\n req.forEach((key, value) => headers[key] = value);\n\n const token = getBearerToken(headers['authorization']);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token,\n headers,\n ip: headers['x-real-ip'] ?? Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n );\n\n if (!res.aborted) {\n res.cork(() => {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n });\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["uWebSockets", "expressify", "querystring"]
|
|
7
7
|
}
|
|
@@ -94,7 +94,7 @@ var uWebSocketsTransport = class extends Transport {
|
|
|
94
94
|
const originalRawSend = this._originalRawSend;
|
|
95
95
|
uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function(...args) {
|
|
96
96
|
let [buf, ...rest] = args;
|
|
97
|
-
buf =
|
|
97
|
+
buf = Buffer.from(buf);
|
|
98
98
|
setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);
|
|
99
99
|
};
|
|
100
100
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/uWebSocketsTransport.ts"],
|
|
4
|
-
"sourcesContent": ["import http, { IncomingHttpHeaders } from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\nimport expressify, { Application } from \"uwebsockets-express\";\n\nimport { AuthContext, HttpServerMock, ErrorCode, matchMaker, getBearerToken, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient.js';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior<any>, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket<any> & {\n url: string,\n query: string,\n context: AuthContext,\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n public expressApp: Application;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n private _originalRawSend: typeof uWebSocketClient.prototype.raw | null = null;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n this.expressApp = expressify(this.app);\n\n if (options.maxBackpressure === undefined) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (options.compression === undefined) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (options.maxPayloadLength === undefined) {\n options.maxPayloadLength = 4 * 1024;\n }\n\n if (options.sendPingsAutomatically === undefined) {\n options.sendPingsAutomatically = true;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n // @ts-ignore\n this.server = new HttpServerMock();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n context: {\n token: getBearerToken(req.getHeader('authorization')),\n headers,\n ip: Buffer.from(res.getRemoteAddressAsText()).toString(),\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'message' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const callback = (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n // @ts-ignore\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n };\n\n if (typeof(port) === \"string\") {\n // @ts-ignore\n this.app.listen_unix(callback, port);\n\n } else {\n this.app.listen(port, callback);\n\n }\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = uWebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function (...args: any[]) {\n // copy buffer\n let [buf, ...rest] = args;\n buf = Array.from(buf);\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient.context);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => client.leave());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.cork(() => {\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n });\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n\n // @ts-ignore\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return res.close();\n }\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // cache all headers\n const headers: IncomingHttpHeaders = {};\n req.forEach((key, value) => headers[key] = value);\n\n const token = getBearerToken(headers['authorization']);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token,\n headers,\n ip: headers['x-real-ip'] ?? Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n );\n\n if (!res.aborted) {\n res.cork(() => {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n });\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import http, { IncomingHttpHeaders } from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\nimport expressify, { Application } from \"uwebsockets-express\";\n\nimport { AuthContext, HttpServerMock, ErrorCode, matchMaker, getBearerToken, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient.js';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior<any>, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket<any> & {\n url: string,\n query: string,\n context: AuthContext,\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n public expressApp: Application;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n private _originalRawSend: typeof uWebSocketClient.prototype.raw | null = null;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n this.expressApp = expressify(this.app);\n\n if (options.maxBackpressure === undefined) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (options.compression === undefined) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (options.maxPayloadLength === undefined) {\n options.maxPayloadLength = 4 * 1024;\n }\n\n if (options.sendPingsAutomatically === undefined) {\n options.sendPingsAutomatically = true;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n // @ts-ignore\n this.server = new HttpServerMock();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n context: {\n token: getBearerToken(req.getHeader('authorization')),\n headers,\n ip: Buffer.from(res.getRemoteAddressAsText()).toString(),\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'message' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const callback = (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n // @ts-ignore\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n };\n\n if (typeof(port) === \"string\") {\n // @ts-ignore\n this.app.listen_unix(callback, port);\n\n } else {\n this.app.listen(port, callback);\n\n }\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = uWebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n uWebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function (...args: any[]) {\n // copy buffer\n let [buf, ...rest] = args;\n buf = Buffer.from(buf);\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient.context);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => client.leave());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.cork(() => {\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n });\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n\n // @ts-ignore\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return res.close();\n }\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // cache all headers\n const headers: IncomingHttpHeaders = {};\n req.forEach((key, value) => headers[key] = value);\n\n const token = getBearerToken(headers['authorization']);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n try {\n if (clientOptions === undefined) {\n throw new Error(\"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token,\n headers,\n ip: headers['x-real-ip'] ?? Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n );\n\n if (!res.aborted) {\n res.cork(() => {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n });\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n // res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/uwebsockets-transport",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.5",
|
|
4
4
|
"input": "./src/index.ts",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"uwebsockets-express": "^1.3.8"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@colyseus/core": "^0.16.
|
|
20
|
+
"@colyseus/core": "^0.16.10"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"@colyseus/core": "0.16.x"
|