@colyseus/core 0.15.0-preview.0 ā 0.15.0-preview.1
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/MatchMaker.js +6 -3
- package/build/MatchMaker.js.map +1 -1
- package/build/MatchMaker.mjs +6 -3
- package/build/MatchMaker.mjs.map +1 -1
- package/build/Server.js +1 -7
- package/build/Server.js.map +1 -1
- package/build/Server.mjs +2 -8
- package/build/Server.mjs.map +1 -1
- package/build/matchmaker/controller.d.ts +16 -0
- package/build/matchmaker/controller.js +19 -0
- package/build/matchmaker/controller.js.map +1 -1
- package/build/matchmaker/controller.mjs +18 -1
- package/build/matchmaker/controller.mjs.map +1 -1
- package/package.json +2 -2
package/build/MatchMaker.js
CHANGED
|
@@ -13,6 +13,7 @@ var SeatReservationError = require('./errors/SeatReservationError.js');
|
|
|
13
13
|
var ServerError = require('./errors/ServerError.js');
|
|
14
14
|
var index = require('./matchmaker/driver/index.js');
|
|
15
15
|
var controller = require('./matchmaker/controller.js');
|
|
16
|
+
var Logger = require('./Logger.js');
|
|
16
17
|
|
|
17
18
|
const handlers = {};
|
|
18
19
|
const rooms = {};
|
|
@@ -72,20 +73,22 @@ async function join(roomName, clientOptions = {}) {
|
|
|
72
73
|
async function reconnect(roomId, clientOptions = {}) {
|
|
73
74
|
const room = await exports.driver.findOne({ roomId });
|
|
74
75
|
if (!room) {
|
|
75
|
-
|
|
76
|
+
Logger.logger.info(`ā room "${roomId}" has been disposed. Did you missed .allowReconnection()?\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);
|
|
77
|
+
throw new ServerError.ServerError(Protocol.ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room "${roomId}" has been disposed.`);
|
|
76
78
|
}
|
|
77
79
|
// check for reconnection
|
|
78
80
|
const reconnectionToken = clientOptions.reconnectionToken;
|
|
79
81
|
if (!reconnectionToken) {
|
|
80
82
|
throw new ServerError.ServerError(Protocol.ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`);
|
|
81
83
|
}
|
|
82
|
-
// respond to
|
|
84
|
+
// respond to re-connection!
|
|
83
85
|
const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);
|
|
84
86
|
if (sessionId) {
|
|
85
87
|
return { room, sessionId };
|
|
86
88
|
}
|
|
87
89
|
else {
|
|
88
|
-
|
|
90
|
+
Logger.logger.info(`ā reconnection token invalid or expired. Did you missed .allowReconnection()?\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);
|
|
91
|
+
throw new ServerError.ServerError(Protocol.ErrorCode.MATCHMAKE_EXPIRED, `reconnection token invalid or expired.`);
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
/**
|
package/build/MatchMaker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatchMaker.js","sources":["../src/MatchMaker.ts"],"sourcesContent":["import { ErrorCode } from './Protocol';\n\nimport { requestFromIPC, subscribeIPC } from './IPC';\nimport { generateId, merge, REMOTE_ROOM_SHORT_TIMEOUT, retry } from './Utils';\n\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Room, RoomInternalState } from './Room';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { Presence } from './presence/Presence';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport { SeatReservationError } from './errors/SeatReservationError';\nimport { ServerError } from './errors/ServerError';\n\nimport { IRoomListingData, MatchMakerDriver, RoomListingData, LocalDriver } from './matchmaker/driver';\nimport * as controller from './matchmaker/controller';\n\nimport { Client } from './Transport';\nimport { Type } from './types';\n\nexport { MatchMakerDriver, controller };\n\nexport type ClientOptions = any;\n\nexport interface SeatReservation {\n sessionId: string;\n room: RoomListingData;\n}\n\nconst handlers: {[id: string]: RegisteredHandler} = {};\nconst rooms: {[roomId: string]: Room} = {};\n\nexport let publicAddress: string;\nexport let processId: string;\nexport let presence: Presence;\nexport let driver: MatchMakerDriver;\n\nlet isGracefullyShuttingDown: boolean;\n\nexport function setup(\n _presence?: Presence,\n _driver?: MatchMakerDriver,\n _processId?: string,\n _publicAddress?: string\n) {\n presence = _presence || new LocalPresence();\n driver = _driver || new LocalDriver();\n processId = _processId;\n publicAddress = _publicAddress;\n\n isGracefullyShuttingDown = false;\n\n /**\n * Subscribe to remote `handleCreateRoom` calls.\n */\n subscribeIPC(presence, processId, getProcessChannel(), (_, args) => {\n return handleCreateRoom.apply(undefined, args);\n });\n\n presence.hset(getRoomCountKey(), processId, '0');\n}\n\n/**\n * Join or create into a room and return seat reservation\n */\nexport async function joinOrCreate(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n let room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n room = await createRoom(roomName, clientOptions);\n }\n\n return await reserveSeatFor(room, clientOptions);\n }, 5, [SeatReservationError]);\n}\n\n/**\n * Create a room and return seat reservation\n */\nexport async function create(roomName: string, clientOptions: ClientOptions = {}) {\n const room = await createRoom(roomName, clientOptions);\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Join a room and return seat reservation\n */\nexport async function join(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n const room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_CRITERIA, `no rooms found with provided criteria`);\n }\n\n return reserveSeatFor(room, clientOptions);\n });\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function reconnect(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n if (!room) { throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`); }\n\n // check for reconnection\n const reconnectionToken = clientOptions.reconnectionToken;\n if (!reconnectionToken) { throw new ServerError(ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`); }\n\n // respond to re-connection!\n const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);\n if (sessionId) {\n return { room, sessionId };\n\n } else {\n throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `invalid reconnection token or expired.`);\n }\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function joinById(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`);\n\n } else if (room.locked) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" is locked`);\n }\n\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Perform a query for all cached rooms\n */\nexport async function query(conditions: Partial<IRoomListingData> = {}) {\n return await driver.find(conditions);\n}\n\n/**\n * Find for a public and unlocked room available\n */\nexport async function findOneRoomAvailable(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n return await awaitRoomAvailable(roomName, async () => {\n const handler = handlers[roomName];\n if (!handler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const roomQuery = driver.findOne({\n locked: false,\n name: roomName,\n private: false,\n ...handler.getFilterOptions(clientOptions),\n });\n\n if (handler.sortOptions) {\n roomQuery.sort(handler.sortOptions);\n }\n\n return await roomQuery;\n });\n}\n\n/**\n * Call a method or return a property on a remote room.\n */\nexport async function remoteRoomCall<R= any>(\n roomId: string,\n method: string,\n args?: any[],\n rejectionTimeout = REMOTE_ROOM_SHORT_TIMEOUT,\n): Promise<R> {\n const room = rooms[roomId];\n\n if (!room) {\n try {\n return await requestFromIPC<R>(presence, getRoomChannel(roomId), method, args);\n\n } catch (e) {\n const request = `${method}${args && ' with args ' + JSON.stringify(args) || ''}`;\n throw new ServerError(\n ErrorCode.MATCHMAKE_UNHANDLED,\n `remote room (${roomId}) timed out, requesting \"${request}\". (${rejectionTimeout}ms exceeded)`,\n );\n }\n\n } else {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : (await room[method].apply(room, args));\n }\n}\n\nexport function defineRoomType<T extends Type<Room>>(\n name: string,\n klass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n) {\n const registeredHandler = new RegisteredHandler(klass, defaultOptions);\n\n handlers[name] = registeredHandler;\n\n cleanupStaleRooms(name);\n\n return registeredHandler;\n}\n\nexport function removeRoomType(name: string) {\n delete handlers[name];\n cleanupStaleRooms(name);\n}\n\nexport function hasHandler(name: string) {\n return handlers[ name ] !== undefined;\n}\n\n/**\n * Create a room\n */\nexport async function createRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const roomsSpawnedByProcessId = await presence.hgetall(getRoomCountKey());\n\n const processIdWithFewerRooms = (\n Object.keys(roomsSpawnedByProcessId).sort((p1, p2) => {\n return (Number(roomsSpawnedByProcessId[p1]) > Number(roomsSpawnedByProcessId[p2]))\n ? 1\n : -1;\n })[0]\n ) || processId;\n\n if (processIdWithFewerRooms === processId) {\n // create the room on this process!\n return await handleCreateRoom(roomName, clientOptions);\n\n } else {\n // ask other process to create the room!\n let room: RoomListingData;\n\n try {\n room = await requestFromIPC<RoomListingData>(\n presence,\n getProcessChannel(processIdWithFewerRooms),\n undefined,\n [roomName, clientOptions],\n REMOTE_ROOM_SHORT_TIMEOUT,\n );\n\n } catch (e) {\n // if other process failed to respond, create the room on this process\n debugAndPrintError(e);\n room = await handleCreateRoom(roomName, clientOptions);\n }\n\n return room;\n }\n}\n\nasync function handleCreateRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const registeredHandler = handlers[roomName];\n\n if (!registeredHandler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const room = new registeredHandler.klass();\n\n // set room public attributes\n room.roomId = generateId();\n room.roomName = roomName;\n room.presence = presence;\n\n const additionalListingData: any = registeredHandler.getFilterOptions(clientOptions);\n\n // assign public host\n if (publicAddress) {\n additionalListingData.publicAddress = publicAddress;\n }\n\n // create a RoomCache reference.\n room.listing = driver.createInstance({\n name: roomName,\n processId,\n ...additionalListingData\n });\n\n if (room.onCreate) {\n try {\n await room.onCreate(merge({}, clientOptions, registeredHandler.options));\n\n // increment amount of rooms this process is handling\n presence.hincrby(getRoomCountKey(), processId, 1);\n\n } catch (e) {\n debugAndPrintError(e);\n throw new ServerError(\n e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n e.message,\n );\n }\n }\n\n room.internalState = RoomInternalState.CREATED;\n\n room.listing.roomId = room.roomId;\n room.listing.maxClients = room.maxClients;\n\n // imediatelly ask client to join the room\n debugMatchMaking('spawning \\'%s\\', roomId: %s, processId: %s', roomName, room.roomId, processId);\n\n room._events.on('lock', lockRoom.bind(this, room));\n room._events.on('unlock', unlockRoom.bind(this, room));\n room._events.on('join', onClientJoinRoom.bind(this, room));\n room._events.on('leave', onClientLeaveRoom.bind(this, room));\n room._events.once('dispose', disposeRoom.bind(this, roomName, room));\n room._events.once('disconnect', () => room._events.removeAllListeners());\n\n // room always start unlocked\n await createRoomReferences(room, true);\n await room.listing.save();\n\n registeredHandler.emit('create', room);\n\n return room.listing;\n}\n\nexport function getRoomById(roomId: string) {\n return rooms[roomId];\n}\n\n/**\n * Disconnects every client on every room in the current process.\n */\nexport function disconnectAll() {\n const promises: Array<Promise<any>> = [];\n\n for (const roomId in rooms) {\n if (!rooms.hasOwnProperty(roomId)) { continue; }\n promises.push(rooms[roomId].disconnect());\n }\n\n return promises;\n}\n\nexport function gracefullyShutdown(): Promise<any> {\n if (isGracefullyShuttingDown) {\n return Promise.reject('already_shutting_down');\n }\n\n isGracefullyShuttingDown = true;\n\n debugMatchMaking(`${processId} is shutting down!`);\n\n // remove processId from room count key\n presence.hdel(getRoomCountKey(), processId);\n\n // unsubscribe from process id channel\n presence.unsubscribe(getProcessChannel());\n\n return Promise.all(disconnectAll());\n}\n\n/**\n * Reserve a seat for a client in a room\n */\nexport async function reserveSeatFor(room: RoomListingData, options: any) {\n const sessionId: string = generateId();\n\n debugMatchMaking(\n 'reserving seat. sessionId: \\'%s\\', roomId: \\'%s\\', processId: \\'%s\\'',\n sessionId, room.roomId, processId,\n );\n\n let successfulSeatReservation: boolean;\n\n try {\n successfulSeatReservation = await remoteRoomCall(room.roomId, '_reserveSeat', [sessionId, options]);\n\n } catch (e) {\n debugMatchMaking(e);\n successfulSeatReservation = false;\n }\n\n if (!successfulSeatReservation) {\n throw new SeatReservationError(`${room.roomId} is already full.`);\n }\n\n return { room, sessionId };\n}\n\nasync function cleanupStaleRooms(roomName: string) {\n //\n // clean-up possibly stale room ids\n // (ungraceful shutdowns using Redis can result on stale room ids still on memory.)\n //\n const cachedRooms = await driver.find({ name: roomName }, { _id: 1 });\n\n // remove connecting counts\n await presence.del(getHandlerConcurrencyKey(roomName));\n\n await Promise.all(cachedRooms.map(async (room) => {\n try {\n // use hardcoded short timeout for cleaning up stale rooms.\n await remoteRoomCall(room.roomId, 'roomId');\n\n } catch (e) {\n debugMatchMaking(`cleaning up stale room '${roomName}', roomId: ${room.roomId}`);\n room.remove();\n }\n }));\n}\n\nasync function createRoomReferences(room: Room, init: boolean = false): Promise<boolean> {\n rooms[room.roomId] = room;\n\n if (init) {\n await subscribeIPC(\n presence,\n processId,\n getRoomChannel(room.roomId),\n (method, args) => {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : room[method].apply(room, args);\n },\n );\n }\n\n return true;\n}\n\nasync function awaitRoomAvailable(roomToJoin: string, callback: Function): Promise<RoomListingData> {\n return new Promise(async (resolve, reject) => {\n const concurrencyKey = getHandlerConcurrencyKey(roomToJoin);\n const concurrency = await presence.incr(concurrencyKey) - 1;\n\n // avoid having too long timeout if 10+ clients ask to join at the same time\n const concurrencyTimeout = Math.min(concurrency * 100, REMOTE_ROOM_SHORT_TIMEOUT);\n\n if (concurrency > 0) {\n debugMatchMaking(\n 'receiving %d concurrent requests for joining \\'%s\\' (waiting %d ms)',\n concurrency, roomToJoin, concurrencyTimeout,\n );\n }\n\n setTimeout(async () => {\n try {\n const result = await callback();\n resolve(result);\n\n } catch (e) {\n reject(e);\n\n } finally {\n await presence.decr(concurrencyKey);\n }\n }, concurrencyTimeout);\n });\n}\n\nfunction onClientJoinRoom(room: Room, client: Client) {\n handlers[room.roomName].emit('join', room, client);\n}\n\nfunction onClientLeaveRoom(room: Room, client: Client, willDispose: boolean) {\n handlers[room.roomName].emit('leave', room, client, willDispose);\n}\n\nfunction lockRoom(room: Room): void {\n // emit public event on registered handler\n handlers[room.roomName].emit('lock', room);\n}\n\nasync function unlockRoom(room: Room) {\n if (await createRoomReferences(room)) {\n // emit public event on registered handler\n handlers[room.roomName].emit('unlock', room);\n }\n}\n\nasync function disposeRoom(roomName: string, room: Room) {\n debugMatchMaking('disposing \\'%s\\' (%s) on processId \\'%s\\'', roomName, room.roomId, processId);\n\n // decrease amount of rooms this process is handling\n if (!isGracefullyShuttingDown) {\n presence.hincrby(getRoomCountKey(), processId, -1);\n }\n\n // remove from room listing (already removed if `disconnect()` has been called)\n if (room.internalState !== RoomInternalState.DISCONNECTING) {\n await room.listing.remove();\n }\n\n // emit disposal on registered session handler\n handlers[roomName].emit('dispose', room);\n\n // remove concurrency key\n presence.del(getHandlerConcurrencyKey(roomName));\n\n // unsubscribe from remote connections\n presence.unsubscribe(getRoomChannel(room.roomId));\n\n // remove actual room reference\n delete rooms[room.roomId];\n}\n\n//\n// Presence keys\n//\n\nfunction getRoomChannel(roomId: string) {\n return `$${roomId}`;\n}\n\nfunction getHandlerConcurrencyKey(name: string) {\n return `c:${name}`;\n}\n\nfunction getProcessChannel(id: string = processId) {\n return `p:${id}`;\n}\n\nfunction getRoomCountKey() {\n return 'roomcount';\n}\n"],"names":["publicAddress","processId","presence","driver","LocalPresence","LocalDriver","subscribeIPC","retry","SeatReservationError","ServerError","ErrorCode","REMOTE_ROOM_SHORT_TIMEOUT","requestFromIPC","RegisteredHandler","debugAndPrintError","generateId","merge","RoomInternalState","debugMatchMaking"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MatchMaker.js","sources":["../src/MatchMaker.ts"],"sourcesContent":["import { ErrorCode } from './Protocol';\n\nimport { requestFromIPC, subscribeIPC } from './IPC';\nimport { generateId, merge, REMOTE_ROOM_SHORT_TIMEOUT, retry } from './Utils';\n\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Room, RoomInternalState } from './Room';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { Presence } from './presence/Presence';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport { SeatReservationError } from './errors/SeatReservationError';\nimport { ServerError } from './errors/ServerError';\n\nimport { IRoomListingData, MatchMakerDriver, RoomListingData, LocalDriver } from './matchmaker/driver';\nimport * as controller from './matchmaker/controller';\n\nimport { logger } from './Logger';\nimport { Client } from './Transport';\nimport { Type } from './types';\n\nexport { MatchMakerDriver, controller };\n\nexport type ClientOptions = any;\n\nexport interface SeatReservation {\n sessionId: string;\n room: RoomListingData;\n}\n\nconst handlers: {[id: string]: RegisteredHandler} = {};\nconst rooms: {[roomId: string]: Room} = {};\n\nexport let publicAddress: string;\nexport let processId: string;\nexport let presence: Presence;\nexport let driver: MatchMakerDriver;\n\nlet isGracefullyShuttingDown: boolean;\n\nexport function setup(\n _presence?: Presence,\n _driver?: MatchMakerDriver,\n _processId?: string,\n _publicAddress?: string\n) {\n presence = _presence || new LocalPresence();\n driver = _driver || new LocalDriver();\n processId = _processId;\n publicAddress = _publicAddress;\n\n isGracefullyShuttingDown = false;\n\n /**\n * Subscribe to remote `handleCreateRoom` calls.\n */\n subscribeIPC(presence, processId, getProcessChannel(), (_, args) => {\n return handleCreateRoom.apply(undefined, args);\n });\n\n presence.hset(getRoomCountKey(), processId, '0');\n}\n\n/**\n * Join or create into a room and return seat reservation\n */\nexport async function joinOrCreate(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n let room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n room = await createRoom(roomName, clientOptions);\n }\n\n return await reserveSeatFor(room, clientOptions);\n }, 5, [SeatReservationError]);\n}\n\n/**\n * Create a room and return seat reservation\n */\nexport async function create(roomName: string, clientOptions: ClientOptions = {}) {\n const room = await createRoom(roomName, clientOptions);\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Join a room and return seat reservation\n */\nexport async function join(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n const room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_CRITERIA, `no rooms found with provided criteria`);\n }\n\n return reserveSeatFor(room, clientOptions);\n });\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function reconnect(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n if (!room) {\n logger.info(`ā room \"${roomId}\" has been disposed. Did you missed .allowReconnection()?\\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" has been disposed.`);\n }\n\n // check for reconnection\n const reconnectionToken = clientOptions.reconnectionToken;\n if (!reconnectionToken) { throw new ServerError(ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`); }\n\n // respond to re-connection!\n const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);\n if (sessionId) {\n return { room, sessionId };\n\n } else {\n logger.info(`ā reconnection token invalid or expired. Did you missed .allowReconnection()?\\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);\n throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `reconnection token invalid or expired.`);\n }\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function joinById(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`);\n\n } else if (room.locked) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" is locked`);\n }\n\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Perform a query for all cached rooms\n */\nexport async function query(conditions: Partial<IRoomListingData> = {}) {\n return await driver.find(conditions);\n}\n\n/**\n * Find for a public and unlocked room available\n */\nexport async function findOneRoomAvailable(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n return await awaitRoomAvailable(roomName, async () => {\n const handler = handlers[roomName];\n if (!handler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const roomQuery = driver.findOne({\n locked: false,\n name: roomName,\n private: false,\n ...handler.getFilterOptions(clientOptions),\n });\n\n if (handler.sortOptions) {\n roomQuery.sort(handler.sortOptions);\n }\n\n return await roomQuery;\n });\n}\n\n/**\n * Call a method or return a property on a remote room.\n */\nexport async function remoteRoomCall<R= any>(\n roomId: string,\n method: string,\n args?: any[],\n rejectionTimeout = REMOTE_ROOM_SHORT_TIMEOUT,\n): Promise<R> {\n const room = rooms[roomId];\n\n if (!room) {\n try {\n return await requestFromIPC<R>(presence, getRoomChannel(roomId), method, args);\n\n } catch (e) {\n const request = `${method}${args && ' with args ' + JSON.stringify(args) || ''}`;\n throw new ServerError(\n ErrorCode.MATCHMAKE_UNHANDLED,\n `remote room (${roomId}) timed out, requesting \"${request}\". (${rejectionTimeout}ms exceeded)`,\n );\n }\n\n } else {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : (await room[method].apply(room, args));\n }\n}\n\nexport function defineRoomType<T extends Type<Room>>(\n name: string,\n klass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n) {\n const registeredHandler = new RegisteredHandler(klass, defaultOptions);\n\n handlers[name] = registeredHandler;\n\n cleanupStaleRooms(name);\n\n return registeredHandler;\n}\n\nexport function removeRoomType(name: string) {\n delete handlers[name];\n cleanupStaleRooms(name);\n}\n\nexport function hasHandler(name: string) {\n return handlers[ name ] !== undefined;\n}\n\n/**\n * Create a room\n */\nexport async function createRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const roomsSpawnedByProcessId = await presence.hgetall(getRoomCountKey());\n\n const processIdWithFewerRooms = (\n Object.keys(roomsSpawnedByProcessId).sort((p1, p2) => {\n return (Number(roomsSpawnedByProcessId[p1]) > Number(roomsSpawnedByProcessId[p2]))\n ? 1\n : -1;\n })[0]\n ) || processId;\n\n if (processIdWithFewerRooms === processId) {\n // create the room on this process!\n return await handleCreateRoom(roomName, clientOptions);\n\n } else {\n // ask other process to create the room!\n let room: RoomListingData;\n\n try {\n room = await requestFromIPC<RoomListingData>(\n presence,\n getProcessChannel(processIdWithFewerRooms),\n undefined,\n [roomName, clientOptions],\n REMOTE_ROOM_SHORT_TIMEOUT,\n );\n\n } catch (e) {\n // if other process failed to respond, create the room on this process\n debugAndPrintError(e);\n room = await handleCreateRoom(roomName, clientOptions);\n }\n\n return room;\n }\n}\n\nasync function handleCreateRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const registeredHandler = handlers[roomName];\n\n if (!registeredHandler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const room = new registeredHandler.klass();\n\n // set room public attributes\n room.roomId = generateId();\n room.roomName = roomName;\n room.presence = presence;\n\n const additionalListingData: any = registeredHandler.getFilterOptions(clientOptions);\n\n // assign public host\n if (publicAddress) {\n additionalListingData.publicAddress = publicAddress;\n }\n\n // create a RoomCache reference.\n room.listing = driver.createInstance({\n name: roomName,\n processId,\n ...additionalListingData\n });\n\n if (room.onCreate) {\n try {\n await room.onCreate(merge({}, clientOptions, registeredHandler.options));\n\n // increment amount of rooms this process is handling\n presence.hincrby(getRoomCountKey(), processId, 1);\n\n } catch (e) {\n debugAndPrintError(e);\n throw new ServerError(\n e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n e.message,\n );\n }\n }\n\n room.internalState = RoomInternalState.CREATED;\n\n room.listing.roomId = room.roomId;\n room.listing.maxClients = room.maxClients;\n\n // imediatelly ask client to join the room\n debugMatchMaking('spawning \\'%s\\', roomId: %s, processId: %s', roomName, room.roomId, processId);\n\n room._events.on('lock', lockRoom.bind(this, room));\n room._events.on('unlock', unlockRoom.bind(this, room));\n room._events.on('join', onClientJoinRoom.bind(this, room));\n room._events.on('leave', onClientLeaveRoom.bind(this, room));\n room._events.once('dispose', disposeRoom.bind(this, roomName, room));\n room._events.once('disconnect', () => room._events.removeAllListeners());\n\n // room always start unlocked\n await createRoomReferences(room, true);\n await room.listing.save();\n\n registeredHandler.emit('create', room);\n\n return room.listing;\n}\n\nexport function getRoomById(roomId: string) {\n return rooms[roomId];\n}\n\n/**\n * Disconnects every client on every room in the current process.\n */\nexport function disconnectAll() {\n const promises: Array<Promise<any>> = [];\n\n for (const roomId in rooms) {\n if (!rooms.hasOwnProperty(roomId)) { continue; }\n promises.push(rooms[roomId].disconnect());\n }\n\n return promises;\n}\n\nexport function gracefullyShutdown(): Promise<any> {\n if (isGracefullyShuttingDown) {\n return Promise.reject('already_shutting_down');\n }\n\n isGracefullyShuttingDown = true;\n\n debugMatchMaking(`${processId} is shutting down!`);\n\n // remove processId from room count key\n presence.hdel(getRoomCountKey(), processId);\n\n // unsubscribe from process id channel\n presence.unsubscribe(getProcessChannel());\n\n return Promise.all(disconnectAll());\n}\n\n/**\n * Reserve a seat for a client in a room\n */\nexport async function reserveSeatFor(room: RoomListingData, options: any) {\n const sessionId: string = generateId();\n\n debugMatchMaking(\n 'reserving seat. sessionId: \\'%s\\', roomId: \\'%s\\', processId: \\'%s\\'',\n sessionId, room.roomId, processId,\n );\n\n let successfulSeatReservation: boolean;\n\n try {\n successfulSeatReservation = await remoteRoomCall(room.roomId, '_reserveSeat', [sessionId, options]);\n\n } catch (e) {\n debugMatchMaking(e);\n successfulSeatReservation = false;\n }\n\n if (!successfulSeatReservation) {\n throw new SeatReservationError(`${room.roomId} is already full.`);\n }\n\n return { room, sessionId };\n}\n\nasync function cleanupStaleRooms(roomName: string) {\n //\n // clean-up possibly stale room ids\n // (ungraceful shutdowns using Redis can result on stale room ids still on memory.)\n //\n const cachedRooms = await driver.find({ name: roomName }, { _id: 1 });\n\n // remove connecting counts\n await presence.del(getHandlerConcurrencyKey(roomName));\n\n await Promise.all(cachedRooms.map(async (room) => {\n try {\n // use hardcoded short timeout for cleaning up stale rooms.\n await remoteRoomCall(room.roomId, 'roomId');\n\n } catch (e) {\n debugMatchMaking(`cleaning up stale room '${roomName}', roomId: ${room.roomId}`);\n room.remove();\n }\n }));\n}\n\nasync function createRoomReferences(room: Room, init: boolean = false): Promise<boolean> {\n rooms[room.roomId] = room;\n\n if (init) {\n await subscribeIPC(\n presence,\n processId,\n getRoomChannel(room.roomId),\n (method, args) => {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : room[method].apply(room, args);\n },\n );\n }\n\n return true;\n}\n\nasync function awaitRoomAvailable(roomToJoin: string, callback: Function): Promise<RoomListingData> {\n return new Promise(async (resolve, reject) => {\n const concurrencyKey = getHandlerConcurrencyKey(roomToJoin);\n const concurrency = await presence.incr(concurrencyKey) - 1;\n\n // avoid having too long timeout if 10+ clients ask to join at the same time\n const concurrencyTimeout = Math.min(concurrency * 100, REMOTE_ROOM_SHORT_TIMEOUT);\n\n if (concurrency > 0) {\n debugMatchMaking(\n 'receiving %d concurrent requests for joining \\'%s\\' (waiting %d ms)',\n concurrency, roomToJoin, concurrencyTimeout,\n );\n }\n\n setTimeout(async () => {\n try {\n const result = await callback();\n resolve(result);\n\n } catch (e) {\n reject(e);\n\n } finally {\n await presence.decr(concurrencyKey);\n }\n }, concurrencyTimeout);\n });\n}\n\nfunction onClientJoinRoom(room: Room, client: Client) {\n handlers[room.roomName].emit('join', room, client);\n}\n\nfunction onClientLeaveRoom(room: Room, client: Client, willDispose: boolean) {\n handlers[room.roomName].emit('leave', room, client, willDispose);\n}\n\nfunction lockRoom(room: Room): void {\n // emit public event on registered handler\n handlers[room.roomName].emit('lock', room);\n}\n\nasync function unlockRoom(room: Room) {\n if (await createRoomReferences(room)) {\n // emit public event on registered handler\n handlers[room.roomName].emit('unlock', room);\n }\n}\n\nasync function disposeRoom(roomName: string, room: Room) {\n debugMatchMaking('disposing \\'%s\\' (%s) on processId \\'%s\\'', roomName, room.roomId, processId);\n\n // decrease amount of rooms this process is handling\n if (!isGracefullyShuttingDown) {\n presence.hincrby(getRoomCountKey(), processId, -1);\n }\n\n // remove from room listing (already removed if `disconnect()` has been called)\n if (room.internalState !== RoomInternalState.DISCONNECTING) {\n await room.listing.remove();\n }\n\n // emit disposal on registered session handler\n handlers[roomName].emit('dispose', room);\n\n // remove concurrency key\n presence.del(getHandlerConcurrencyKey(roomName));\n\n // unsubscribe from remote connections\n presence.unsubscribe(getRoomChannel(room.roomId));\n\n // remove actual room reference\n delete rooms[room.roomId];\n}\n\n//\n// Presence keys\n//\n\nfunction getRoomChannel(roomId: string) {\n return `$${roomId}`;\n}\n\nfunction getHandlerConcurrencyKey(name: string) {\n return `c:${name}`;\n}\n\nfunction getProcessChannel(id: string = processId) {\n return `p:${id}`;\n}\n\nfunction getRoomCountKey() {\n return 'roomcount';\n}\n"],"names":["publicAddress","processId","presence","driver","LocalPresence","LocalDriver","subscribeIPC","retry","SeatReservationError","ServerError","ErrorCode","logger","REMOTE_ROOM_SHORT_TIMEOUT","requestFromIPC","RegisteredHandler","debugAndPrintError","generateId","merge","RoomInternalState","debugMatchMaking"],"mappings":"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"}
|
package/build/MatchMaker.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { ServerError } from './errors/ServerError.mjs';
|
|
|
10
10
|
import { LocalDriver } from './matchmaker/driver/index.mjs';
|
|
11
11
|
import * as controller from './matchmaker/controller.mjs';
|
|
12
12
|
export { controller };
|
|
13
|
+
import { logger } from './Logger.mjs';
|
|
13
14
|
|
|
14
15
|
const handlers = {};
|
|
15
16
|
const rooms = {};
|
|
@@ -69,20 +70,22 @@ async function join(roomName, clientOptions = {}) {
|
|
|
69
70
|
async function reconnect(roomId, clientOptions = {}) {
|
|
70
71
|
const room = await driver.findOne({ roomId });
|
|
71
72
|
if (!room) {
|
|
72
|
-
|
|
73
|
+
logger.info(`ā room "${roomId}" has been disposed. Did you missed .allowReconnection()?\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);
|
|
74
|
+
throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room "${roomId}" has been disposed.`);
|
|
73
75
|
}
|
|
74
76
|
// check for reconnection
|
|
75
77
|
const reconnectionToken = clientOptions.reconnectionToken;
|
|
76
78
|
if (!reconnectionToken) {
|
|
77
79
|
throw new ServerError(ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`);
|
|
78
80
|
}
|
|
79
|
-
// respond to
|
|
81
|
+
// respond to re-connection!
|
|
80
82
|
const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);
|
|
81
83
|
if (sessionId) {
|
|
82
84
|
return { room, sessionId };
|
|
83
85
|
}
|
|
84
86
|
else {
|
|
85
|
-
|
|
87
|
+
logger.info(`ā reconnection token invalid or expired. Did you missed .allowReconnection()?\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);
|
|
88
|
+
throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `reconnection token invalid or expired.`);
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
/**
|
package/build/MatchMaker.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatchMaker.mjs","sources":["../src/MatchMaker.ts"],"sourcesContent":["import { ErrorCode } from './Protocol';\n\nimport { requestFromIPC, subscribeIPC } from './IPC';\nimport { generateId, merge, REMOTE_ROOM_SHORT_TIMEOUT, retry } from './Utils';\n\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Room, RoomInternalState } from './Room';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { Presence } from './presence/Presence';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport { SeatReservationError } from './errors/SeatReservationError';\nimport { ServerError } from './errors/ServerError';\n\nimport { IRoomListingData, MatchMakerDriver, RoomListingData, LocalDriver } from './matchmaker/driver';\nimport * as controller from './matchmaker/controller';\n\nimport { Client } from './Transport';\nimport { Type } from './types';\n\nexport { MatchMakerDriver, controller };\n\nexport type ClientOptions = any;\n\nexport interface SeatReservation {\n sessionId: string;\n room: RoomListingData;\n}\n\nconst handlers: {[id: string]: RegisteredHandler} = {};\nconst rooms: {[roomId: string]: Room} = {};\n\nexport let publicAddress: string;\nexport let processId: string;\nexport let presence: Presence;\nexport let driver: MatchMakerDriver;\n\nlet isGracefullyShuttingDown: boolean;\n\nexport function setup(\n _presence?: Presence,\n _driver?: MatchMakerDriver,\n _processId?: string,\n _publicAddress?: string\n) {\n presence = _presence || new LocalPresence();\n driver = _driver || new LocalDriver();\n processId = _processId;\n publicAddress = _publicAddress;\n\n isGracefullyShuttingDown = false;\n\n /**\n * Subscribe to remote `handleCreateRoom` calls.\n */\n subscribeIPC(presence, processId, getProcessChannel(), (_, args) => {\n return handleCreateRoom.apply(undefined, args);\n });\n\n presence.hset(getRoomCountKey(), processId, '0');\n}\n\n/**\n * Join or create into a room and return seat reservation\n */\nexport async function joinOrCreate(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n let room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n room = await createRoom(roomName, clientOptions);\n }\n\n return await reserveSeatFor(room, clientOptions);\n }, 5, [SeatReservationError]);\n}\n\n/**\n * Create a room and return seat reservation\n */\nexport async function create(roomName: string, clientOptions: ClientOptions = {}) {\n const room = await createRoom(roomName, clientOptions);\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Join a room and return seat reservation\n */\nexport async function join(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n const room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_CRITERIA, `no rooms found with provided criteria`);\n }\n\n return reserveSeatFor(room, clientOptions);\n });\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function reconnect(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n if (!room) { throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`); }\n\n // check for reconnection\n const reconnectionToken = clientOptions.reconnectionToken;\n if (!reconnectionToken) { throw new ServerError(ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`); }\n\n // respond to re-connection!\n const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);\n if (sessionId) {\n return { room, sessionId };\n\n } else {\n throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `invalid reconnection token or expired.`);\n }\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function joinById(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`);\n\n } else if (room.locked) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" is locked`);\n }\n\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Perform a query for all cached rooms\n */\nexport async function query(conditions: Partial<IRoomListingData> = {}) {\n return await driver.find(conditions);\n}\n\n/**\n * Find for a public and unlocked room available\n */\nexport async function findOneRoomAvailable(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n return await awaitRoomAvailable(roomName, async () => {\n const handler = handlers[roomName];\n if (!handler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const roomQuery = driver.findOne({\n locked: false,\n name: roomName,\n private: false,\n ...handler.getFilterOptions(clientOptions),\n });\n\n if (handler.sortOptions) {\n roomQuery.sort(handler.sortOptions);\n }\n\n return await roomQuery;\n });\n}\n\n/**\n * Call a method or return a property on a remote room.\n */\nexport async function remoteRoomCall<R= any>(\n roomId: string,\n method: string,\n args?: any[],\n rejectionTimeout = REMOTE_ROOM_SHORT_TIMEOUT,\n): Promise<R> {\n const room = rooms[roomId];\n\n if (!room) {\n try {\n return await requestFromIPC<R>(presence, getRoomChannel(roomId), method, args);\n\n } catch (e) {\n const request = `${method}${args && ' with args ' + JSON.stringify(args) || ''}`;\n throw new ServerError(\n ErrorCode.MATCHMAKE_UNHANDLED,\n `remote room (${roomId}) timed out, requesting \"${request}\". (${rejectionTimeout}ms exceeded)`,\n );\n }\n\n } else {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : (await room[method].apply(room, args));\n }\n}\n\nexport function defineRoomType<T extends Type<Room>>(\n name: string,\n klass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n) {\n const registeredHandler = new RegisteredHandler(klass, defaultOptions);\n\n handlers[name] = registeredHandler;\n\n cleanupStaleRooms(name);\n\n return registeredHandler;\n}\n\nexport function removeRoomType(name: string) {\n delete handlers[name];\n cleanupStaleRooms(name);\n}\n\nexport function hasHandler(name: string) {\n return handlers[ name ] !== undefined;\n}\n\n/**\n * Create a room\n */\nexport async function createRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const roomsSpawnedByProcessId = await presence.hgetall(getRoomCountKey());\n\n const processIdWithFewerRooms = (\n Object.keys(roomsSpawnedByProcessId).sort((p1, p2) => {\n return (Number(roomsSpawnedByProcessId[p1]) > Number(roomsSpawnedByProcessId[p2]))\n ? 1\n : -1;\n })[0]\n ) || processId;\n\n if (processIdWithFewerRooms === processId) {\n // create the room on this process!\n return await handleCreateRoom(roomName, clientOptions);\n\n } else {\n // ask other process to create the room!\n let room: RoomListingData;\n\n try {\n room = await requestFromIPC<RoomListingData>(\n presence,\n getProcessChannel(processIdWithFewerRooms),\n undefined,\n [roomName, clientOptions],\n REMOTE_ROOM_SHORT_TIMEOUT,\n );\n\n } catch (e) {\n // if other process failed to respond, create the room on this process\n debugAndPrintError(e);\n room = await handleCreateRoom(roomName, clientOptions);\n }\n\n return room;\n }\n}\n\nasync function handleCreateRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const registeredHandler = handlers[roomName];\n\n if (!registeredHandler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const room = new registeredHandler.klass();\n\n // set room public attributes\n room.roomId = generateId();\n room.roomName = roomName;\n room.presence = presence;\n\n const additionalListingData: any = registeredHandler.getFilterOptions(clientOptions);\n\n // assign public host\n if (publicAddress) {\n additionalListingData.publicAddress = publicAddress;\n }\n\n // create a RoomCache reference.\n room.listing = driver.createInstance({\n name: roomName,\n processId,\n ...additionalListingData\n });\n\n if (room.onCreate) {\n try {\n await room.onCreate(merge({}, clientOptions, registeredHandler.options));\n\n // increment amount of rooms this process is handling\n presence.hincrby(getRoomCountKey(), processId, 1);\n\n } catch (e) {\n debugAndPrintError(e);\n throw new ServerError(\n e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n e.message,\n );\n }\n }\n\n room.internalState = RoomInternalState.CREATED;\n\n room.listing.roomId = room.roomId;\n room.listing.maxClients = room.maxClients;\n\n // imediatelly ask client to join the room\n debugMatchMaking('spawning \\'%s\\', roomId: %s, processId: %s', roomName, room.roomId, processId);\n\n room._events.on('lock', lockRoom.bind(this, room));\n room._events.on('unlock', unlockRoom.bind(this, room));\n room._events.on('join', onClientJoinRoom.bind(this, room));\n room._events.on('leave', onClientLeaveRoom.bind(this, room));\n room._events.once('dispose', disposeRoom.bind(this, roomName, room));\n room._events.once('disconnect', () => room._events.removeAllListeners());\n\n // room always start unlocked\n await createRoomReferences(room, true);\n await room.listing.save();\n\n registeredHandler.emit('create', room);\n\n return room.listing;\n}\n\nexport function getRoomById(roomId: string) {\n return rooms[roomId];\n}\n\n/**\n * Disconnects every client on every room in the current process.\n */\nexport function disconnectAll() {\n const promises: Array<Promise<any>> = [];\n\n for (const roomId in rooms) {\n if (!rooms.hasOwnProperty(roomId)) { continue; }\n promises.push(rooms[roomId].disconnect());\n }\n\n return promises;\n}\n\nexport function gracefullyShutdown(): Promise<any> {\n if (isGracefullyShuttingDown) {\n return Promise.reject('already_shutting_down');\n }\n\n isGracefullyShuttingDown = true;\n\n debugMatchMaking(`${processId} is shutting down!`);\n\n // remove processId from room count key\n presence.hdel(getRoomCountKey(), processId);\n\n // unsubscribe from process id channel\n presence.unsubscribe(getProcessChannel());\n\n return Promise.all(disconnectAll());\n}\n\n/**\n * Reserve a seat for a client in a room\n */\nexport async function reserveSeatFor(room: RoomListingData, options: any) {\n const sessionId: string = generateId();\n\n debugMatchMaking(\n 'reserving seat. sessionId: \\'%s\\', roomId: \\'%s\\', processId: \\'%s\\'',\n sessionId, room.roomId, processId,\n );\n\n let successfulSeatReservation: boolean;\n\n try {\n successfulSeatReservation = await remoteRoomCall(room.roomId, '_reserveSeat', [sessionId, options]);\n\n } catch (e) {\n debugMatchMaking(e);\n successfulSeatReservation = false;\n }\n\n if (!successfulSeatReservation) {\n throw new SeatReservationError(`${room.roomId} is already full.`);\n }\n\n return { room, sessionId };\n}\n\nasync function cleanupStaleRooms(roomName: string) {\n //\n // clean-up possibly stale room ids\n // (ungraceful shutdowns using Redis can result on stale room ids still on memory.)\n //\n const cachedRooms = await driver.find({ name: roomName }, { _id: 1 });\n\n // remove connecting counts\n await presence.del(getHandlerConcurrencyKey(roomName));\n\n await Promise.all(cachedRooms.map(async (room) => {\n try {\n // use hardcoded short timeout for cleaning up stale rooms.\n await remoteRoomCall(room.roomId, 'roomId');\n\n } catch (e) {\n debugMatchMaking(`cleaning up stale room '${roomName}', roomId: ${room.roomId}`);\n room.remove();\n }\n }));\n}\n\nasync function createRoomReferences(room: Room, init: boolean = false): Promise<boolean> {\n rooms[room.roomId] = room;\n\n if (init) {\n await subscribeIPC(\n presence,\n processId,\n getRoomChannel(room.roomId),\n (method, args) => {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : room[method].apply(room, args);\n },\n );\n }\n\n return true;\n}\n\nasync function awaitRoomAvailable(roomToJoin: string, callback: Function): Promise<RoomListingData> {\n return new Promise(async (resolve, reject) => {\n const concurrencyKey = getHandlerConcurrencyKey(roomToJoin);\n const concurrency = await presence.incr(concurrencyKey) - 1;\n\n // avoid having too long timeout if 10+ clients ask to join at the same time\n const concurrencyTimeout = Math.min(concurrency * 100, REMOTE_ROOM_SHORT_TIMEOUT);\n\n if (concurrency > 0) {\n debugMatchMaking(\n 'receiving %d concurrent requests for joining \\'%s\\' (waiting %d ms)',\n concurrency, roomToJoin, concurrencyTimeout,\n );\n }\n\n setTimeout(async () => {\n try {\n const result = await callback();\n resolve(result);\n\n } catch (e) {\n reject(e);\n\n } finally {\n await presence.decr(concurrencyKey);\n }\n }, concurrencyTimeout);\n });\n}\n\nfunction onClientJoinRoom(room: Room, client: Client) {\n handlers[room.roomName].emit('join', room, client);\n}\n\nfunction onClientLeaveRoom(room: Room, client: Client, willDispose: boolean) {\n handlers[room.roomName].emit('leave', room, client, willDispose);\n}\n\nfunction lockRoom(room: Room): void {\n // emit public event on registered handler\n handlers[room.roomName].emit('lock', room);\n}\n\nasync function unlockRoom(room: Room) {\n if (await createRoomReferences(room)) {\n // emit public event on registered handler\n handlers[room.roomName].emit('unlock', room);\n }\n}\n\nasync function disposeRoom(roomName: string, room: Room) {\n debugMatchMaking('disposing \\'%s\\' (%s) on processId \\'%s\\'', roomName, room.roomId, processId);\n\n // decrease amount of rooms this process is handling\n if (!isGracefullyShuttingDown) {\n presence.hincrby(getRoomCountKey(), processId, -1);\n }\n\n // remove from room listing (already removed if `disconnect()` has been called)\n if (room.internalState !== RoomInternalState.DISCONNECTING) {\n await room.listing.remove();\n }\n\n // emit disposal on registered session handler\n handlers[roomName].emit('dispose', room);\n\n // remove concurrency key\n presence.del(getHandlerConcurrencyKey(roomName));\n\n // unsubscribe from remote connections\n presence.unsubscribe(getRoomChannel(room.roomId));\n\n // remove actual room reference\n delete rooms[room.roomId];\n}\n\n//\n// Presence keys\n//\n\nfunction getRoomChannel(roomId: string) {\n return `$${roomId}`;\n}\n\nfunction getHandlerConcurrencyKey(name: string) {\n return `c:${name}`;\n}\n\nfunction getProcessChannel(id: string = processId) {\n return `p:${id}`;\n}\n\nfunction getRoomCountKey() {\n return 'roomcount';\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MatchMaker.mjs","sources":["../src/MatchMaker.ts"],"sourcesContent":["import { ErrorCode } from './Protocol';\n\nimport { requestFromIPC, subscribeIPC } from './IPC';\nimport { generateId, merge, REMOTE_ROOM_SHORT_TIMEOUT, retry } from './Utils';\n\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Room, RoomInternalState } from './Room';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { Presence } from './presence/Presence';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport { SeatReservationError } from './errors/SeatReservationError';\nimport { ServerError } from './errors/ServerError';\n\nimport { IRoomListingData, MatchMakerDriver, RoomListingData, LocalDriver } from './matchmaker/driver';\nimport * as controller from './matchmaker/controller';\n\nimport { logger } from './Logger';\nimport { Client } from './Transport';\nimport { Type } from './types';\n\nexport { MatchMakerDriver, controller };\n\nexport type ClientOptions = any;\n\nexport interface SeatReservation {\n sessionId: string;\n room: RoomListingData;\n}\n\nconst handlers: {[id: string]: RegisteredHandler} = {};\nconst rooms: {[roomId: string]: Room} = {};\n\nexport let publicAddress: string;\nexport let processId: string;\nexport let presence: Presence;\nexport let driver: MatchMakerDriver;\n\nlet isGracefullyShuttingDown: boolean;\n\nexport function setup(\n _presence?: Presence,\n _driver?: MatchMakerDriver,\n _processId?: string,\n _publicAddress?: string\n) {\n presence = _presence || new LocalPresence();\n driver = _driver || new LocalDriver();\n processId = _processId;\n publicAddress = _publicAddress;\n\n isGracefullyShuttingDown = false;\n\n /**\n * Subscribe to remote `handleCreateRoom` calls.\n */\n subscribeIPC(presence, processId, getProcessChannel(), (_, args) => {\n return handleCreateRoom.apply(undefined, args);\n });\n\n presence.hset(getRoomCountKey(), processId, '0');\n}\n\n/**\n * Join or create into a room and return seat reservation\n */\nexport async function joinOrCreate(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n let room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n room = await createRoom(roomName, clientOptions);\n }\n\n return await reserveSeatFor(room, clientOptions);\n }, 5, [SeatReservationError]);\n}\n\n/**\n * Create a room and return seat reservation\n */\nexport async function create(roomName: string, clientOptions: ClientOptions = {}) {\n const room = await createRoom(roomName, clientOptions);\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Join a room and return seat reservation\n */\nexport async function join(roomName: string, clientOptions: ClientOptions = {}) {\n return await retry<Promise<SeatReservation>>(async () => {\n const room = await findOneRoomAvailable(roomName, clientOptions);\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_CRITERIA, `no rooms found with provided criteria`);\n }\n\n return reserveSeatFor(room, clientOptions);\n });\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function reconnect(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n if (!room) {\n logger.info(`ā room \"${roomId}\" has been disposed. Did you missed .allowReconnection()?\\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" has been disposed.`);\n }\n\n // check for reconnection\n const reconnectionToken = clientOptions.reconnectionToken;\n if (!reconnectionToken) { throw new ServerError(ErrorCode.MATCHMAKE_UNHANDLED, `'reconnectionToken' must be provided for reconnection.`); }\n\n // respond to re-connection!\n const sessionId = await remoteRoomCall(room.roomId, 'checkReconnectionToken', [reconnectionToken]);\n if (sessionId) {\n return { room, sessionId };\n\n } else {\n logger.info(`ā reconnection token invalid or expired. Did you missed .allowReconnection()?\\nš https://docs.colyseus.io/colyseus/server/room/#allowreconnection-client-seconds`);\n throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `reconnection token invalid or expired.`);\n }\n}\n\n/**\n * Join a room by id and return seat reservation\n */\nexport async function joinById(roomId: string, clientOptions: ClientOptions = {}) {\n const room = await driver.findOne({ roomId });\n\n if (!room) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" not found`);\n\n } else if (room.locked) {\n throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room \"${roomId}\" is locked`);\n }\n\n return reserveSeatFor(room, clientOptions);\n}\n\n/**\n * Perform a query for all cached rooms\n */\nexport async function query(conditions: Partial<IRoomListingData> = {}) {\n return await driver.find(conditions);\n}\n\n/**\n * Find for a public and unlocked room available\n */\nexport async function findOneRoomAvailable(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n return await awaitRoomAvailable(roomName, async () => {\n const handler = handlers[roomName];\n if (!handler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const roomQuery = driver.findOne({\n locked: false,\n name: roomName,\n private: false,\n ...handler.getFilterOptions(clientOptions),\n });\n\n if (handler.sortOptions) {\n roomQuery.sort(handler.sortOptions);\n }\n\n return await roomQuery;\n });\n}\n\n/**\n * Call a method or return a property on a remote room.\n */\nexport async function remoteRoomCall<R= any>(\n roomId: string,\n method: string,\n args?: any[],\n rejectionTimeout = REMOTE_ROOM_SHORT_TIMEOUT,\n): Promise<R> {\n const room = rooms[roomId];\n\n if (!room) {\n try {\n return await requestFromIPC<R>(presence, getRoomChannel(roomId), method, args);\n\n } catch (e) {\n const request = `${method}${args && ' with args ' + JSON.stringify(args) || ''}`;\n throw new ServerError(\n ErrorCode.MATCHMAKE_UNHANDLED,\n `remote room (${roomId}) timed out, requesting \"${request}\". (${rejectionTimeout}ms exceeded)`,\n );\n }\n\n } else {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : (await room[method].apply(room, args));\n }\n}\n\nexport function defineRoomType<T extends Type<Room>>(\n name: string,\n klass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n) {\n const registeredHandler = new RegisteredHandler(klass, defaultOptions);\n\n handlers[name] = registeredHandler;\n\n cleanupStaleRooms(name);\n\n return registeredHandler;\n}\n\nexport function removeRoomType(name: string) {\n delete handlers[name];\n cleanupStaleRooms(name);\n}\n\nexport function hasHandler(name: string) {\n return handlers[ name ] !== undefined;\n}\n\n/**\n * Create a room\n */\nexport async function createRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const roomsSpawnedByProcessId = await presence.hgetall(getRoomCountKey());\n\n const processIdWithFewerRooms = (\n Object.keys(roomsSpawnedByProcessId).sort((p1, p2) => {\n return (Number(roomsSpawnedByProcessId[p1]) > Number(roomsSpawnedByProcessId[p2]))\n ? 1\n : -1;\n })[0]\n ) || processId;\n\n if (processIdWithFewerRooms === processId) {\n // create the room on this process!\n return await handleCreateRoom(roomName, clientOptions);\n\n } else {\n // ask other process to create the room!\n let room: RoomListingData;\n\n try {\n room = await requestFromIPC<RoomListingData>(\n presence,\n getProcessChannel(processIdWithFewerRooms),\n undefined,\n [roomName, clientOptions],\n REMOTE_ROOM_SHORT_TIMEOUT,\n );\n\n } catch (e) {\n // if other process failed to respond, create the room on this process\n debugAndPrintError(e);\n room = await handleCreateRoom(roomName, clientOptions);\n }\n\n return room;\n }\n}\n\nasync function handleCreateRoom(roomName: string, clientOptions: ClientOptions): Promise<RoomListingData> {\n const registeredHandler = handlers[roomName];\n\n if (!registeredHandler) {\n throw new ServerError( ErrorCode.MATCHMAKE_NO_HANDLER, `provided room name \"${roomName}\" not defined`);\n }\n\n const room = new registeredHandler.klass();\n\n // set room public attributes\n room.roomId = generateId();\n room.roomName = roomName;\n room.presence = presence;\n\n const additionalListingData: any = registeredHandler.getFilterOptions(clientOptions);\n\n // assign public host\n if (publicAddress) {\n additionalListingData.publicAddress = publicAddress;\n }\n\n // create a RoomCache reference.\n room.listing = driver.createInstance({\n name: roomName,\n processId,\n ...additionalListingData\n });\n\n if (room.onCreate) {\n try {\n await room.onCreate(merge({}, clientOptions, registeredHandler.options));\n\n // increment amount of rooms this process is handling\n presence.hincrby(getRoomCountKey(), processId, 1);\n\n } catch (e) {\n debugAndPrintError(e);\n throw new ServerError(\n e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n e.message,\n );\n }\n }\n\n room.internalState = RoomInternalState.CREATED;\n\n room.listing.roomId = room.roomId;\n room.listing.maxClients = room.maxClients;\n\n // imediatelly ask client to join the room\n debugMatchMaking('spawning \\'%s\\', roomId: %s, processId: %s', roomName, room.roomId, processId);\n\n room._events.on('lock', lockRoom.bind(this, room));\n room._events.on('unlock', unlockRoom.bind(this, room));\n room._events.on('join', onClientJoinRoom.bind(this, room));\n room._events.on('leave', onClientLeaveRoom.bind(this, room));\n room._events.once('dispose', disposeRoom.bind(this, roomName, room));\n room._events.once('disconnect', () => room._events.removeAllListeners());\n\n // room always start unlocked\n await createRoomReferences(room, true);\n await room.listing.save();\n\n registeredHandler.emit('create', room);\n\n return room.listing;\n}\n\nexport function getRoomById(roomId: string) {\n return rooms[roomId];\n}\n\n/**\n * Disconnects every client on every room in the current process.\n */\nexport function disconnectAll() {\n const promises: Array<Promise<any>> = [];\n\n for (const roomId in rooms) {\n if (!rooms.hasOwnProperty(roomId)) { continue; }\n promises.push(rooms[roomId].disconnect());\n }\n\n return promises;\n}\n\nexport function gracefullyShutdown(): Promise<any> {\n if (isGracefullyShuttingDown) {\n return Promise.reject('already_shutting_down');\n }\n\n isGracefullyShuttingDown = true;\n\n debugMatchMaking(`${processId} is shutting down!`);\n\n // remove processId from room count key\n presence.hdel(getRoomCountKey(), processId);\n\n // unsubscribe from process id channel\n presence.unsubscribe(getProcessChannel());\n\n return Promise.all(disconnectAll());\n}\n\n/**\n * Reserve a seat for a client in a room\n */\nexport async function reserveSeatFor(room: RoomListingData, options: any) {\n const sessionId: string = generateId();\n\n debugMatchMaking(\n 'reserving seat. sessionId: \\'%s\\', roomId: \\'%s\\', processId: \\'%s\\'',\n sessionId, room.roomId, processId,\n );\n\n let successfulSeatReservation: boolean;\n\n try {\n successfulSeatReservation = await remoteRoomCall(room.roomId, '_reserveSeat', [sessionId, options]);\n\n } catch (e) {\n debugMatchMaking(e);\n successfulSeatReservation = false;\n }\n\n if (!successfulSeatReservation) {\n throw new SeatReservationError(`${room.roomId} is already full.`);\n }\n\n return { room, sessionId };\n}\n\nasync function cleanupStaleRooms(roomName: string) {\n //\n // clean-up possibly stale room ids\n // (ungraceful shutdowns using Redis can result on stale room ids still on memory.)\n //\n const cachedRooms = await driver.find({ name: roomName }, { _id: 1 });\n\n // remove connecting counts\n await presence.del(getHandlerConcurrencyKey(roomName));\n\n await Promise.all(cachedRooms.map(async (room) => {\n try {\n // use hardcoded short timeout for cleaning up stale rooms.\n await remoteRoomCall(room.roomId, 'roomId');\n\n } catch (e) {\n debugMatchMaking(`cleaning up stale room '${roomName}', roomId: ${room.roomId}`);\n room.remove();\n }\n }));\n}\n\nasync function createRoomReferences(room: Room, init: boolean = false): Promise<boolean> {\n rooms[room.roomId] = room;\n\n if (init) {\n await subscribeIPC(\n presence,\n processId,\n getRoomChannel(room.roomId),\n (method, args) => {\n return (!args && typeof (room[method]) !== 'function')\n ? room[method]\n : room[method].apply(room, args);\n },\n );\n }\n\n return true;\n}\n\nasync function awaitRoomAvailable(roomToJoin: string, callback: Function): Promise<RoomListingData> {\n return new Promise(async (resolve, reject) => {\n const concurrencyKey = getHandlerConcurrencyKey(roomToJoin);\n const concurrency = await presence.incr(concurrencyKey) - 1;\n\n // avoid having too long timeout if 10+ clients ask to join at the same time\n const concurrencyTimeout = Math.min(concurrency * 100, REMOTE_ROOM_SHORT_TIMEOUT);\n\n if (concurrency > 0) {\n debugMatchMaking(\n 'receiving %d concurrent requests for joining \\'%s\\' (waiting %d ms)',\n concurrency, roomToJoin, concurrencyTimeout,\n );\n }\n\n setTimeout(async () => {\n try {\n const result = await callback();\n resolve(result);\n\n } catch (e) {\n reject(e);\n\n } finally {\n await presence.decr(concurrencyKey);\n }\n }, concurrencyTimeout);\n });\n}\n\nfunction onClientJoinRoom(room: Room, client: Client) {\n handlers[room.roomName].emit('join', room, client);\n}\n\nfunction onClientLeaveRoom(room: Room, client: Client, willDispose: boolean) {\n handlers[room.roomName].emit('leave', room, client, willDispose);\n}\n\nfunction lockRoom(room: Room): void {\n // emit public event on registered handler\n handlers[room.roomName].emit('lock', room);\n}\n\nasync function unlockRoom(room: Room) {\n if (await createRoomReferences(room)) {\n // emit public event on registered handler\n handlers[room.roomName].emit('unlock', room);\n }\n}\n\nasync function disposeRoom(roomName: string, room: Room) {\n debugMatchMaking('disposing \\'%s\\' (%s) on processId \\'%s\\'', roomName, room.roomId, processId);\n\n // decrease amount of rooms this process is handling\n if (!isGracefullyShuttingDown) {\n presence.hincrby(getRoomCountKey(), processId, -1);\n }\n\n // remove from room listing (already removed if `disconnect()` has been called)\n if (room.internalState !== RoomInternalState.DISCONNECTING) {\n await room.listing.remove();\n }\n\n // emit disposal on registered session handler\n handlers[roomName].emit('dispose', room);\n\n // remove concurrency key\n presence.del(getHandlerConcurrencyKey(roomName));\n\n // unsubscribe from remote connections\n presence.unsubscribe(getRoomChannel(room.roomId));\n\n // remove actual room reference\n delete rooms[room.roomId];\n}\n\n//\n// Presence keys\n//\n\nfunction getRoomChannel(roomId: string) {\n return `$${roomId}`;\n}\n\nfunction getHandlerConcurrencyKey(name: string) {\n return `c:${name}`;\n}\n\nfunction getProcessChannel(id: string = processId) {\n return `p:${id}`;\n}\n\nfunction getRoomCountKey() {\n return 'roomcount';\n}\n"],"names":[],"mappings":"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"}
|
package/build/Server.js
CHANGED
|
@@ -175,13 +175,7 @@ class Server {
|
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
177
|
async handleMatchMakeRequest(req, res) {
|
|
178
|
-
const headers = {
|
|
179
|
-
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
|
|
180
|
-
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
|
|
181
|
-
'Access-Control-Allow-Origin': '*',
|
|
182
|
-
'Access-Control-Max-Age': 2592000,
|
|
183
|
-
// ...
|
|
184
|
-
};
|
|
178
|
+
const headers = Object.assign({}, controller.DEFAULT_CORS_HEADERS, controller.getCorsHeaders.call(undefined, req));
|
|
185
179
|
if (req.method === 'OPTIONS') {
|
|
186
180
|
res.writeHead(204, headers);
|
|
187
181
|
res.end();
|
package/build/Server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.js","sources":["../src/Server.ts"],"sourcesContent":["import http, { IncomingMessage, ServerResponse } from 'http';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './Utils';\n\nimport {generateId} from '.';\nimport { registerNode, unregisterNode } from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\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 protected processId: string = generateId();\n\n protected port: number;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true } = options;\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n\n // \"presence\" option is not used from now on\n delete options.presence;\n this.attach(options);\n\n // setup matchmaker\n matchMaker.setup(\n this.presence,\n this.driver,\n this.processId,\n options.publicAddress,\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(\"š 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 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 return new Promise<void>((resolve, reject) => {\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 registerNode(this.presence, {\n port: this.port,\n processId: this.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 handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n await unregisterNode(this.presence, {\n port: this.port,\n processId: this.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit(err ? 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 logger.warn(`š¶ļøā Colyseus latency simulation enabled ā ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = 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(() => _onMessage.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 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 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 const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\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 const clientOptions = JSON.parse(Buffer.concat(data).toString());\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\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 const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n}\n"],"names":["generateId","LocalPresence","LocalDriver","matchMaker.setup","registerGracefulShutdown","setLogger","logger","registerNode","matchMaker.defineRoomType","unregisterNode","matchMaker.gracefullyShutdown","debugAndPrintError","Room","matchMaker.controller.matchmakeRoute","debugMatchMaking","matchMaker.controller.allowedRoomNameChars","matchMaker.controller.invokeMethod","matchMaker.controller.getAvailableRooms"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Server.js","sources":["../src/Server.ts"],"sourcesContent":["import http, { IncomingMessage, ServerResponse } from 'http';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './Utils';\n\nimport {generateId} from '.';\nimport { registerNode, unregisterNode } from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\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 protected processId: string = generateId();\n\n protected port: number;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true } = options;\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n\n // \"presence\" option is not used from now on\n delete options.presence;\n this.attach(options);\n\n // setup matchmaker\n matchMaker.setup(\n this.presence,\n this.driver,\n this.processId,\n options.publicAddress,\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(\"š 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 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 return new Promise<void>((resolve, reject) => {\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 registerNode(this.presence, {\n port: this.port,\n processId: this.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 handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n await unregisterNode(this.presence, {\n port: this.port,\n processId: this.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit(err ? 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 logger.warn(`š¶ļøā Colyseus latency simulation enabled ā ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = 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(() => _onMessage.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 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 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 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 const clientOptions = JSON.parse(Buffer.concat(data).toString());\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\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 const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n}\n"],"names":["generateId","LocalPresence","LocalDriver","matchMaker.setup","registerGracefulShutdown","setLogger","logger","registerNode","matchMaker.defineRoomType","unregisterNode","matchMaker.gracefullyShutdown","debugAndPrintError","Room","matchMaker.controller.matchmakeRoute","debugMatchMaking","matchMaker.controller.DEFAULT_CORS_HEADERS","matchMaker.controller.getCorsHeaders","matchMaker.controller.allowedRoomNameChars","matchMaker.controller.invokeMethod","matchMaker.controller.getAvailableRooms"],"mappings":"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"}
|
package/build/Server.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import 'events';
|
|
|
12
12
|
import './Transport.mjs';
|
|
13
13
|
import '@colyseus/schema';
|
|
14
14
|
import './rooms/RelayRoom.mjs';
|
|
15
|
-
import { matchmakeRoute, allowedRoomNameChars, invokeMethod, getAvailableRooms } from './matchmaker/controller.mjs';
|
|
15
|
+
import { matchmakeRoute, DEFAULT_CORS_HEADERS, getCorsHeaders, allowedRoomNameChars, invokeMethod, getAvailableRooms } from './matchmaker/controller.mjs';
|
|
16
16
|
|
|
17
17
|
class Server {
|
|
18
18
|
transport;
|
|
@@ -171,13 +171,7 @@ class Server {
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
async handleMatchMakeRequest(req, res) {
|
|
174
|
-
const headers = {
|
|
175
|
-
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
|
|
176
|
-
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
|
|
177
|
-
'Access-Control-Allow-Origin': '*',
|
|
178
|
-
'Access-Control-Max-Age': 2592000,
|
|
179
|
-
// ...
|
|
180
|
-
};
|
|
174
|
+
const headers = Object.assign({}, DEFAULT_CORS_HEADERS, getCorsHeaders.call(undefined, req));
|
|
181
175
|
if (req.method === 'OPTIONS') {
|
|
182
176
|
res.writeHead(204, headers);
|
|
183
177
|
res.end();
|
package/build/Server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Server.mjs","sources":["../src/Server.ts"],"sourcesContent":["import http, { IncomingMessage, ServerResponse } from 'http';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './Utils';\n\nimport {generateId} from '.';\nimport { registerNode, unregisterNode } from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\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 protected processId: string = generateId();\n\n protected port: number;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true } = options;\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n\n // \"presence\" option is not used from now on\n delete options.presence;\n this.attach(options);\n\n // setup matchmaker\n matchMaker.setup(\n this.presence,\n this.driver,\n this.processId,\n options.publicAddress,\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(\"š 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 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 return new Promise<void>((resolve, reject) => {\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 registerNode(this.presence, {\n port: this.port,\n processId: this.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 handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n await unregisterNode(this.presence, {\n port: this.port,\n processId: this.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit(err ? 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 logger.warn(`š¶ļøā Colyseus latency simulation enabled ā ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = 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(() => _onMessage.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 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 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 const headers = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': 2592000,\n // ...\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 const clientOptions = JSON.parse(Buffer.concat(data).toString());\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\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 const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n}\n"],"names":["matchMaker.setup","matchMaker.defineRoomType","matchMaker.gracefullyShutdown","matchMaker.controller.matchmakeRoute","matchMaker.controller.allowedRoomNameChars","matchMaker.controller.invokeMethod","matchMaker.controller.getAvailableRooms"],"mappings":";;;;;;;;;;;;;;;;MA+Ca,MAAM;IACV,SAAS,CAAY;IAElB,QAAQ,CAAW;IACnB,MAAM,CAA8B;IACpC,SAAS,GAAW,UAAU,EAAE,CAAC;IAEjC,IAAI,CAAS;IAEvB,YAAY,UAAyB,EAAE;QACrC,MAAM,EAAE,kBAAkB,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;QAE9C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,aAAa,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;;QAGlD,OAAO,OAAO,CAAC,QAAQ,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;;QAGrBA,KAAgB,CACd,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,SAAS,EACd,OAAO,CAAC,aAAa,CACtB,CAAC;QAEF,IAAI,kBAAkB,EAAE;YACtB,wBAAwB,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;SACvE;QAED,IAAG,OAAO,CAAC,MAAM,EAAE;YACjB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC3B;KACF;IAEM,MAAM,CAAC,OAAsB;;;;;QAKlC,IACE,OAAO,CAAC,YAAY,KAAK,SAAS;YAClC,OAAO,CAAC,cAAc,KAAK,SAAS;YACpC,OAAO,CAAC,MAAM,KAAK,SAAS;YAC5B,OAAO,CAAC,YAAY,KAAK,SAAS,EAClC;YACA,MAAM,CAAC,IAAI,CAAC,6JAA6J,CAAC,CAAC;YAC3K,MAAM,CAAC,IAAI,CAAC;;;;;;;GAOf,CAAC,CAAC;YACC,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAA;SAC5E;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACzE,OAAO,OAAO,CAAC,SAAS,CAAC;QAEzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC,2BAA2B,EAAE,CAAC,CAAC;YAClF,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAqB,CAAC,CAAC;SACpE;KACF;;;;;;;;;IAUM,MAAM,MAAM,CAAC,IAAY,EAAE,QAAiB,EAAE,OAAgB,EAAE,iBAA4B;QACjG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM;YACvC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,GAAG;gBACjD,IAAI,iBAAiB,EAAE;oBACrB,iBAAiB,CAAC,GAAG,CAAC,CAAC;iBACxB;gBAED,IAAI,GAAG,EAAE;oBACP,MAAM,CAAC,GAAG,CAAC,CAAC;iBAEb;qBAAM;oBACL,OAAO,EAAE,CAAC;iBACX;aACF,CAAC,CAAC;SACJ,CAAC,CAAC;KACJ;IAEM,MAAM,2BAA2B;;QAEtC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;KACJ;;;;;;;;IASM,MAAM,CACX,IAAY,EACZ,OAAU,EACV,cAAwE;QAExE,OAAOC,cAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;KACjE;IAEM,MAAM,kBAAkB,CAAC,OAAgB,IAAI,EAAE,GAAW;QAC/D,MAAM,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE;YAClC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QAEH,IAAI;YACF,MAAMC,kBAA6B,EAAE,CAAC;YAEtC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAEvB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;SAEjC;QAAC,OAAO,CAAC,EAAE;YACV,kBAAkB,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;SAEnD;gBAAS;YACR,IAAI,IAAI,EAAE;gBACR,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;aAC3B;SACF;KACF;;;;;IAMM,eAAe,CAAC,YAAoB;QACzC,MAAM,CAAC,IAAI,CAAC,8CAA8C,YAAY,4BAA4B,CAAC,CAAC;QAEpG,MAAM,SAAS,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;;QAG1C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;;QAEhD,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,UAAU,MAAM,EAAE,MAAM;;YAErD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzC,UAAU,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;SAC1E,CAAC;KACH;;;;;IAMM,UAAU,CAAC,QAAmC;QACnD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;KACpC;IAES,mBAAmB,CAAC,CAAM;QAClC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;KACnF;IAES,kBAAkB,GAC1B,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;IAEf,uBAAuB,CAAC,MAAmB;QACnD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG;YAC5B,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAIC,cAAoC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE;gBACtE,gBAAgB,CAAC,gCAAgC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC5D,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;aAEvC;iBAAM;gBACL,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;oBAChD,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;iBACrC;aACF;SACF,CAAC,CAAC;KACJ;IAES,MAAM,sBAAsB,CAAC,GAAoB,EAAE,GAAmB;QAC9E,MAAM,OAAO,GAAG;YACd,8BAA8B,EAAE,gDAAgD;YAChF,8BAA8B,EAAE,oBAAoB;YACpD,6BAA6B,EAAE,GAAG;YAClC,wBAAwB,EAAE,OAAO;;SAElC,CAAC;QAEF,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE;YAC5B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC5B,GAAG,CAAC,GAAG,EAAE,CAAC;SAEX;aAAM,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE;YAChC,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAACC,oBAA0C,CAAC,CAAC;YAChF,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAACD,cAAoC,CAAC,CAAC;YACnF,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;YACjD,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAc,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAEzD,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE;gBACZ,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;gBAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAE5B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACjE,IAAI;oBACF,MAAM,QAAQ,GAAG,MAAME,YAAkC,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;oBAC3F,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;iBAErC;gBAAC,OAAO,CAAC,EAAE;oBACV,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;iBAChE;gBAED,GAAG,CAAC,GAAG,EAAE,CAAC;aACX,CAAC,CAAC;SAEJ;aAAM,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE;YAC/B,MAAM,aAAa,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAACD,oBAA0C,CAAC,CAAC;YAChF,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAEzF,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC5B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAME,iBAAuC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACnF,GAAG,CAAC,GAAG,EAAE,CAAC;SACX;KAEF;;;;;"}
|
|
1
|
+
{"version":3,"file":"Server.mjs","sources":["../src/Server.ts"],"sourcesContent":["import http, { IncomingMessage, ServerResponse } from 'http';\n\nimport { debugAndPrintError, debugMatchMaking } from './Debug';\nimport * as matchMaker from './MatchMaker';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler';\nimport { Presence } from './presence/Presence';\n\nimport { Room } from './Room';\nimport { Type } from './types';\nimport { registerGracefulShutdown } from './Utils';\n\nimport {generateId} from '.';\nimport { registerNode, unregisterNode } from './discovery';\n\nimport { LocalPresence } from './presence/LocalPresence';\nimport { LocalDriver } from './matchmaker/driver';\n\nimport { Transport } from './Transport';\nimport { logger, setLogger } from './Logger';\n\n// IServerOptions &\nexport type ServerOptions = {\n publicAddress?: string,\n\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\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 protected processId: string = generateId();\n\n protected port: number;\n\n constructor(options: ServerOptions = {}) {\n const { gracefullyShutdown = true } = options;\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n\n // \"presence\" option is not used from now on\n delete options.presence;\n this.attach(options);\n\n // setup matchmaker\n matchMaker.setup(\n this.presence,\n this.driver,\n this.processId,\n options.publicAddress,\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(\"š 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 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 return new Promise<void>((resolve, reject) => {\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 registerNode(this.presence, {\n port: this.port,\n processId: this.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 handler Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n name: string,\n handler: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n ): RegisteredHandler {\n return matchMaker.defineRoomType(name, handler, defaultOptions);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n await unregisterNode(this.presence, {\n port: this.port,\n processId: this.processId,\n });\n\n try {\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n this.driver.shutdown();\n\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit(err ? 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 logger.warn(`š¶ļøā Colyseus latency simulation enabled ā ${milliseconds}ms latency for round trip.`);\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n /* tslint:disable:no-string-literal */\n const _onMessage = Room.prototype['_onMessage'];\n /* tslint:disable:no-string-literal */\n Room.prototype['_onMessage'] = 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(() => _onMessage.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 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 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 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 const clientOptions = JSON.parse(Buffer.concat(data).toString());\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\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 const matchedParams = req.url.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n headers['Content-Type'] = 'application/json';\n res.writeHead(200, headers);\n res.write(JSON.stringify(await matchMaker.controller.getAvailableRooms(roomName)));\n res.end();\n }\n\n }\n\n}\n"],"names":["matchMaker.setup","matchMaker.defineRoomType","matchMaker.gracefullyShutdown","matchMaker.controller.matchmakeRoute","matchMaker.controller.DEFAULT_CORS_HEADERS","matchMaker.controller.getCorsHeaders","matchMaker.controller.allowedRoomNameChars","matchMaker.controller.invokeMethod","matchMaker.controller.getAvailableRooms"],"mappings":"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"}
|
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
* Matchmaking controller
|
|
3
3
|
* (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* You may manually change the default corsHeaders by overwriting its values via:
|
|
7
|
+
* ```
|
|
8
|
+
* import { matchMaker } from "@colyseus/core";
|
|
9
|
+
* matchMaker.controller.corsHeaders['Access-Control-Allow-Origin']
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_CORS_HEADERS: {
|
|
13
|
+
'Access-Control-Allow-Headers': string;
|
|
14
|
+
'Access-Control-Allow-Methods': string;
|
|
15
|
+
'Access-Control-Allow-Origin': string;
|
|
16
|
+
'Access-Control-Max-Age': string;
|
|
17
|
+
};
|
|
18
|
+
export declare let getCorsHeaders: (request: any) => {
|
|
19
|
+
[header: string]: string;
|
|
20
|
+
};
|
|
5
21
|
export declare const exposedMethods: string[];
|
|
6
22
|
export declare const allowedRoomNameChars: RegExp;
|
|
7
23
|
export declare const matchmakeRoute = "matchmake";
|
|
@@ -10,6 +10,23 @@ var MatchMaker = require('../MatchMaker.js');
|
|
|
10
10
|
* Matchmaking controller
|
|
11
11
|
* (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)
|
|
12
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* You may manually change the default corsHeaders by overwriting its values via:
|
|
15
|
+
* ```
|
|
16
|
+
* import { matchMaker } from "@colyseus/core";
|
|
17
|
+
* matchMaker.controller.corsHeaders['Access-Control-Allow-Origin']
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_CORS_HEADERS = {
|
|
21
|
+
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
|
|
22
|
+
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
|
|
23
|
+
'Access-Control-Allow-Origin': '*',
|
|
24
|
+
'Access-Control-Max-Age': '2592000',
|
|
25
|
+
// ...
|
|
26
|
+
};
|
|
27
|
+
let getCorsHeaders = function (request) {
|
|
28
|
+
return {};
|
|
29
|
+
};
|
|
13
30
|
const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];
|
|
14
31
|
const allowedRoomNameChars = /([a-zA-Z_\-0-9]+)/gi;
|
|
15
32
|
const matchmakeRoute = 'matchmake';
|
|
@@ -38,9 +55,11 @@ async function invokeMethod(method, roomName, clientOptions = {}) {
|
|
|
38
55
|
}
|
|
39
56
|
}
|
|
40
57
|
|
|
58
|
+
exports.DEFAULT_CORS_HEADERS = DEFAULT_CORS_HEADERS;
|
|
41
59
|
exports.allowedRoomNameChars = allowedRoomNameChars;
|
|
42
60
|
exports.exposedMethods = exposedMethods;
|
|
43
61
|
exports.getAvailableRooms = getAvailableRooms;
|
|
62
|
+
exports.getCorsHeaders = getCorsHeaders;
|
|
44
63
|
exports.invokeMethod = invokeMethod;
|
|
45
64
|
exports.matchmakeRoute = matchmakeRoute;
|
|
46
65
|
//# sourceMappingURL=controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sources":["../../src/matchmaker/controller.ts"],"sourcesContent":["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];\nexport const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\nexport const matchmakeRoute = 'matchmake';\n\nexport function getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n}\n\nexport async function invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n}\n"],"names":["matchMaker.query","ServerError","ErrorCode","matchMaker"],"mappings":";;;;;;;;AAAA;;;;
|
|
1
|
+
{"version":3,"file":"controller.js","sources":["../../src/matchmaker/controller.ts"],"sourcesContent":["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\n/**\n * You may manually change the default corsHeaders by overwriting its values via:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.corsHeaders['Access-Control-Allow-Origin']\n * ```\n */\n\nexport const DEFAULT_CORS_HEADERS = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n};\n\nexport let getCorsHeaders = function (request: any): { [header: string]: string } {\n return {};\n};\n\nexport const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];\nexport const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\nexport const matchmakeRoute = 'matchmake';\n\nexport function getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n}\n\nexport async function invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n}\n"],"names":["matchMaker.query","ServerError","ErrorCode","matchMaker"],"mappings":";;;;;;;;AAAA;;;;AASA;;;;;;;MAQa,oBAAoB,GAAG;IAClC,8BAA8B,EAAE,gDAAgD;IAChF,8BAA8B,EAAE,oBAAoB;IACpD,6BAA6B,EAAE,GAAG;IAClC,wBAAwB,EAAE,SAAS;;EAEnC;IAES,cAAc,GAAG,UAAU,OAAY;IAChD,OAAO,EAAE,CAAC;AACZ,EAAE;MAEW,cAAc,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE;MAC7E,oBAAoB,GAAG,sBAAsB;MAC7C,cAAc,GAAG,YAAY;SAE1B,iBAAiB,CAAC,QAAgB;;;;IAI9C,MAAM,UAAU,GAAQ;QACpB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,KAAK;KACjB,CAAC;IACF,IAAI,QAAQ,EAAE;QACV,UAAU,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;KACjC;IACD,OAAOA,gBAAgB,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAEM,eAAe,YAAY,CAAC,MAAc,EAAE,QAAgB,EAAE,gBAAqB,EAAE;IACxF,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;QACvC,MAAM,IAAIC,uBAAW,CAACC,kBAAS,CAAC,oBAAoB,EAAE,mBAAmB,MAAM,GAAG,CAAC,CAAC;KACvF;IAED,IAAI;QACA,OAAO,MAAMC,UAAU,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KAE5D;IAAC,OAAO,CAAC,EAAE;QACR,MAAM,IAAIF,uBAAW,CAAC,CAAC,CAAC,IAAI,IAAIC,kBAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;KAC7E;AACL;;;;;;;;;;"}
|
|
@@ -7,6 +7,23 @@ import { query } from '../MatchMaker.mjs';
|
|
|
7
7
|
* Matchmaking controller
|
|
8
8
|
* (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)
|
|
9
9
|
*/
|
|
10
|
+
/**
|
|
11
|
+
* You may manually change the default corsHeaders by overwriting its values via:
|
|
12
|
+
* ```
|
|
13
|
+
* import { matchMaker } from "@colyseus/core";
|
|
14
|
+
* matchMaker.controller.corsHeaders['Access-Control-Allow-Origin']
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_CORS_HEADERS = {
|
|
18
|
+
'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
|
|
19
|
+
'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
|
|
20
|
+
'Access-Control-Allow-Origin': '*',
|
|
21
|
+
'Access-Control-Max-Age': '2592000',
|
|
22
|
+
// ...
|
|
23
|
+
};
|
|
24
|
+
let getCorsHeaders = function (request) {
|
|
25
|
+
return {};
|
|
26
|
+
};
|
|
10
27
|
const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];
|
|
11
28
|
const allowedRoomNameChars = /([a-zA-Z_\-0-9]+)/gi;
|
|
12
29
|
const matchmakeRoute = 'matchmake';
|
|
@@ -35,5 +52,5 @@ async function invokeMethod(method, roomName, clientOptions = {}) {
|
|
|
35
52
|
}
|
|
36
53
|
}
|
|
37
54
|
|
|
38
|
-
export { allowedRoomNameChars, exposedMethods, getAvailableRooms, invokeMethod, matchmakeRoute };
|
|
55
|
+
export { DEFAULT_CORS_HEADERS, allowedRoomNameChars, exposedMethods, getAvailableRooms, getCorsHeaders, invokeMethod, matchmakeRoute };
|
|
39
56
|
//# sourceMappingURL=controller.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.mjs","sources":["../../src/matchmaker/controller.ts"],"sourcesContent":["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\nexport const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];\nexport const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\nexport const matchmakeRoute = 'matchmake';\n\nexport function getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n}\n\nexport async function invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n}\n"],"names":["matchMaker.query","matchMaker"],"mappings":";;;;;AAAA;;;;
|
|
1
|
+
{"version":3,"file":"controller.mjs","sources":["../../src/matchmaker/controller.ts"],"sourcesContent":["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from \"../Protocol\";\nimport { ServerError } from \"../errors/ServerError\";\nimport * as matchMaker from \"../MatchMaker\";\n\n/**\n * You may manually change the default corsHeaders by overwriting its values via:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.corsHeaders['Access-Control-Allow-Origin']\n * ```\n */\n\nexport const DEFAULT_CORS_HEADERS = {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n};\n\nexport let getCorsHeaders = function (request: any): { [header: string]: string } {\n return {};\n};\n\nexport const exposedMethods = ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'];\nexport const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\nexport const matchmakeRoute = 'matchmake';\n\nexport function getAvailableRooms(roomName: string) {\n /**\n * list public & unlocked rooms\n */\n const conditions: any = {\n locked: false,\n private: false,\n };\n if (roomName) {\n conditions[\"name\"] = roomName;\n }\n return matchMaker.query(conditions);\n}\n\nexport async function invokeMethod(method: string, roomName: string, clientOptions: any = {}) {\n if (exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions);\n\n } catch (e) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n}\n"],"names":["matchMaker.query","matchMaker"],"mappings":";;;;;AAAA;;;;AASA;;;;;;;MAQa,oBAAoB,GAAG;IAClC,8BAA8B,EAAE,gDAAgD;IAChF,8BAA8B,EAAE,oBAAoB;IACpD,6BAA6B,EAAE,GAAG;IAClC,wBAAwB,EAAE,SAAS;;EAEnC;IAES,cAAc,GAAG,UAAU,OAAY;IAChD,OAAO,EAAE,CAAC;AACZ,EAAE;MAEW,cAAc,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE;MAC7E,oBAAoB,GAAG,sBAAsB;MAC7C,cAAc,GAAG,YAAY;SAE1B,iBAAiB,CAAC,QAAgB;;;;IAI9C,MAAM,UAAU,GAAQ;QACpB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,KAAK;KACjB,CAAC;IACF,IAAI,QAAQ,EAAE;QACV,UAAU,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;KACjC;IACD,OAAOA,KAAgB,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAEM,eAAe,YAAY,CAAC,MAAc,EAAE,QAAgB,EAAE,gBAAqB,EAAE;IACxF,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;QACvC,MAAM,IAAI,WAAW,CAAC,SAAS,CAAC,oBAAoB,EAAE,mBAAmB,MAAM,GAAG,CAAC,CAAC;KACvF;IAED,IAAI;QACA,OAAO,MAAMC,UAAU,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;KAE5D;IAAC,OAAO,CAAC,EAAE;QACR,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;KAC7E;AACL;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/core",
|
|
3
|
-
"version": "0.15.0-preview.
|
|
3
|
+
"version": "0.15.0-preview.1",
|
|
4
4
|
"description": "Multiplayer Framework for Node.js.",
|
|
5
5
|
"input": "./src/index.ts",
|
|
6
6
|
"main": "./build/index.js",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "119700e1d3605855ec19c0deff7fde987f9f21b1"
|
|
48
48
|
}
|