@colyseus/core 0.16.23 → 0.16.24
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/Server.js +0 -1
- package/build/Server.js.map +2 -2
- package/build/Server.mjs +0 -1
- package/build/Server.mjs.map +2 -2
- package/package.json +1 -1
package/build/Server.js
CHANGED
|
@@ -79,7 +79,6 @@ class Server {
|
|
|
79
79
|
import_Logger.logger.warn("\u{1F449} Documentation: https://docs.colyseus.io/server/transport/");
|
|
80
80
|
}
|
|
81
81
|
const transport = options.transport || this.getDefaultTransport(options);
|
|
82
|
-
delete options.transport;
|
|
83
82
|
this.transport = transport;
|
|
84
83
|
if (this.transport.server) {
|
|
85
84
|
this.transport.server.once("listening", () => this.registerProcessForDiscovery());
|
package/build/Server.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/Server.ts"],
|
|
4
|
-
"sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug.js';\nimport * as matchMaker from './MatchMaker.js';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.js';\nimport { Presence } from './presence/Presence.js';\n\nimport { Room } from './Room.js';\nimport { Type } from './utils/types.js';\nimport { getBearerToken, registerGracefulShutdown } from './utils/Utils.js';\n\nimport { registerNode, unregisterNode} from './discovery/index.js';\n\nimport { LocalPresence } from './presence/LocalPresence.js';\nimport { LocalDriver } from './matchmaker/driver/local/LocalDriver.js';\n\nimport { Transport } from './Transport.js';\nimport { logger, setLogger } from './Logger.js';\nimport { setDevMode, isDevMode } from './utils/DevMode.js';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n // @ts-ignore\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n // @ts-ignore\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token: getBearerToken(req.headers['authorization']),\n headers: req.headers,\n ip: req.headers['x-real-ip'] ?? req.headers['x-forwarded-for'] ?? req.socket.remoteAddress,\n req,\n },\n );\n\n // specify protocol, if available.\n if (this.transport.protocol !== undefined) {\n response.protocol = this.transport.protocol;\n }\n\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n res.writeHead(404, headers);\n res.end();\n }\n\n }\n\n\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,6BAAqB;AAErB,mBAAqD;AACrD,iBAA4B;AAI5B,kBAAqB;AAErB,mBAAyD;AAEzD,uBAA4C;AAE5C,2BAA8B;AAC9B,yBAA4B;AAG5B,oBAAkC;AAClC,qBAAsC;AAoD/B,MAAM,OAAO;AAAA,EAYlB,YAAY,UAAyB,CAAC,GAAG;AAFzC;AAAA,SAAQ,yBAAkE;
|
|
4
|
+
"sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug.js';\nimport * as matchMaker from './MatchMaker.js';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.js';\nimport { Presence } from './presence/Presence.js';\n\nimport { Room } from './Room.js';\nimport { Type } from './utils/types.js';\nimport { getBearerToken, registerGracefulShutdown } from './utils/Utils.js';\n\nimport { registerNode, unregisterNode} from './discovery/index.js';\n\nimport { LocalPresence } from './presence/LocalPresence.js';\nimport { LocalDriver } from './matchmaker/driver/local/LocalDriver.js';\n\nimport { Transport } from './Transport.js';\nimport { logger, setLogger } from './Logger.js';\nimport { setDevMode, isDevMode } from './utils/DevMode.js';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n\n this.transport = transport;\n\n if (this.transport.server) {\n // @ts-ignore\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n // @ts-ignore\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token: getBearerToken(req.headers['authorization']),\n headers: req.headers,\n ip: req.headers['x-real-ip'] ?? req.headers['x-forwarded-for'] ?? req.socket.remoteAddress,\n req,\n },\n );\n\n // specify protocol, if available.\n if (this.transport.protocol !== undefined) {\n response.protocol = this.transport.protocol;\n }\n\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n res.writeHead(404, headers);\n res.end();\n }\n\n }\n\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["greeting"]
|
|
7
7
|
}
|
package/build/Server.mjs
CHANGED
|
@@ -48,7 +48,6 @@ var Server = class {
|
|
|
48
48
|
logger.warn("\u{1F449} Documentation: https://docs.colyseus.io/server/transport/");
|
|
49
49
|
}
|
|
50
50
|
const transport = options.transport || this.getDefaultTransport(options);
|
|
51
|
-
delete options.transport;
|
|
52
51
|
this.transport = transport;
|
|
53
52
|
if (this.transport.server) {
|
|
54
53
|
this.transport.server.once("listening", () => this.registerProcessForDiscovery());
|
package/build/Server.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/Server.ts"],
|
|
4
|
-
"sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug.js';\nimport * as matchMaker from './MatchMaker.js';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.js';\nimport { Presence } from './presence/Presence.js';\n\nimport { Room } from './Room.js';\nimport { Type } from './utils/types.js';\nimport { getBearerToken, registerGracefulShutdown } from './utils/Utils.js';\n\nimport { registerNode, unregisterNode} from './discovery/index.js';\n\nimport { LocalPresence } from './presence/LocalPresence.js';\nimport { LocalDriver } from './matchmaker/driver/local/LocalDriver.js';\n\nimport { Transport } from './Transport.js';\nimport { logger, setLogger } from './Logger.js';\nimport { setDevMode, isDevMode } from './utils/DevMode.js';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n\n this.transport = transport;\n\n if (this.transport.server) {\n // @ts-ignore\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n // @ts-ignore\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token: getBearerToken(req.headers['authorization']),\n headers: req.headers,\n ip: req.headers['x-real-ip'] ?? req.headers['x-forwarded-for'] ?? req.socket.remoteAddress,\n req,\n },\n );\n\n // specify protocol, if available.\n if (this.transport.protocol !== undefined) {\n response.protocol = this.transport.protocol;\n }\n\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n res.writeHead(404, headers);\n res.end();\n }\n\n }\n\n\n}\n"],
|
|
5
|
-
"mappings": ";AACA,OAAO,cAAc;AAErB,SAAS,oBAAoB,wBAAwB;AACrD,YAAY,gBAAgB;AAI5B,SAAS,YAAY;AAErB,SAAS,gBAAgB,gCAAgC;AAEzD,SAAS,cAAc,sBAAqB;AAE5C,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAG5B,SAAS,QAAQ,iBAAiB;AAClC,SAAS,YAAY,iBAAiB;AAoD/B,IAAM,SAAN,MAAa;AAAA,EAYlB,YAAY,UAAyB,CAAC,GAAG;AAFzC;AAAA,SAAQ,yBAAkE;
|
|
4
|
+
"sourcesContent": ["import http, { IncomingMessage, ServerResponse } from 'http';\nimport greeting from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug.js';\nimport * as matchMaker from './MatchMaker.js';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.js';\nimport { Presence } from './presence/Presence.js';\n\nimport { Room } from './Room.js';\nimport { Type } from './utils/types.js';\nimport { getBearerToken, registerGracefulShutdown } from './utils/Utils.js';\n\nimport { registerNode, unregisterNode} from './discovery/index.js';\n\nimport { LocalPresence } from './presence/LocalPresence.js';\nimport { LocalDriver } from './matchmaker/driver/local/LocalDriver.js';\n\nimport { Transport } from './Transport.js';\nimport { logger, setLogger } from './Logger.js';\nimport { setDevMode, isDevMode } from './utils/DevMode.js';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n\n /**\n * Options below are now part of WebSocketTransport (@colyseus/ws-transport)\n * TODO: remove me on 0.15.0\n */\n /** @deprecated */\n pingInterval?: number,\n\n /** @deprecated */\n pingMaxRetries?: number,\n\n /** @deprecated */\n verifyClient?: any,\n\n /** @deprecated */\n server?: http.Server,\n};\n\nexport class Server {\n public transport: Transport;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number;\n protected greet: boolean;\n\n //@ts-expect-error\n private _originalRoomOnMessage: typeof Room.prototype._onMessage | null = null;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true, greet = true } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n /**\n * Display deprecation warnings for moved Transport options.\n * TODO: Remove me on 0.15\n */\n if (\n options.pingInterval !== undefined ||\n options.pingMaxRetries !== undefined ||\n options.server !== undefined ||\n options.verifyClient !== undefined\n ) {\n logger.warn(\"DEPRECATION WARNING: 'pingInterval', 'pingMaxRetries', 'server', and 'verifyClient' Server options will be permanently moved to WebSocketTransport on v0.15\");\n logger.warn(`new Server({\n transport: new WebSocketTransport({\n pingInterval: ...,\n pingMaxRetries: ...,\n server: ...,\n verifyClient: ...\n })\n})`);\n logger.warn(\"\uD83D\uDC49 Documentation: https://docs.colyseus.io/server/transport/\")\n }\n\n const transport = options.transport || this.getDefaultTransport(options);\n\n this.transport = transport;\n\n if (this.transport.server) {\n // @ts-ignore\n this.transport.server.once('listening', () => this.registerProcessForDiscovery());\n this.attachMatchMakingRoutes(this.transport.server as http.Server);\n }\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function) {\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n console.log(greeting);\n }\n\n return new Promise<void>((resolve, reject) => {\n // @ts-ignore\n this.transport.server?.on('error', (err) => reject(err));\n this.transport.listen(port, hostname, backlog, (err) => {\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n public async registerProcessForDiscovery() {\n // register node for proxy/service discovery\n await registerNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n await unregisterNode(this.presence, {\n port: this.port,\n processId: matchMaker.processId,\n });\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n await matchMaker.gracefullyShutdown();\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n /* tslint:disable:no-string-literal */\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected attachMatchMakingRoutes(server: http.Server) {\n const listeners = server.listeners('request').slice(0);\n server.removeAllListeners('request');\n\n server.on('request', (req, res) => {\n if (req.url.indexOf(`/${matchMaker.controller.matchmakeRoute}`) !== -1) {\n debugMatchMaking('received matchmake request: %s', req.url);\n this.handleMatchMakeRequest(req, res);\n\n } else {\n for (let i = 0, l = listeners.length; i < l; i++) {\n listeners[i].call(server, req, res);\n }\n }\n });\n }\n\n protected async handleMatchMakeRequest(req: IncomingMessage, res: ServerResponse) {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n res.writeHead(503, {});\n res.end();\n return;\n }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, headers);\n res.end();\n\n } else if (req.method === 'POST') {\n const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n const data = [];\n req.on('data', (chunk) => data.push(chunk));\n req.on('end', async () => {\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n\n try {\n const clientOptions = JSON.parse(Buffer.concat(data).toString());\n const response = await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n {\n token: getBearerToken(req.headers['authorization']),\n headers: req.headers,\n ip: req.headers['x-real-ip'] ?? req.headers['x-forwarded-for'] ?? req.socket.remoteAddress,\n req,\n },\n );\n\n // specify protocol, if available.\n if (this.transport.protocol !== undefined) {\n response.protocol = this.transport.protocol;\n }\n\n res.write(JSON.stringify(response));\n\n } catch (e) {\n res.write(JSON.stringify({ code: e.code, error: e.message, }));\n }\n\n res.end();\n });\n\n } else if (req.method === 'GET') {\n res.writeHead(404, headers);\n res.end();\n }\n\n }\n\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["gracefullyShutdown"]
|
|
7
7
|
}
|