@colyseus/uwebsockets-transport 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.
@@ -22,6 +22,7 @@ export declare class uWebSocketClient implements Client {
22
22
  _afterNextPatchQueue: any;
23
23
  _reconnectionToken: string;
24
24
  constructor(id: string, ref: uWebSocketWrapper);
25
+ sendBytes(type: any, bytes?: any | ISendOptions, options?: ISendOptions): void;
25
26
  send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions): void;
26
27
  enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;
27
28
  raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;
@@ -39,11 +39,15 @@ class uWebSocketClient {
39
39
  this.sessionId = id;
40
40
  ref.on('close', () => this.readyState = exports.ReadyState.CLOSED);
41
41
  }
42
+ sendBytes(type, bytes, options) {
43
+ core.debugMessage("send bytes(to %s): '%s' -> %j", this.sessionId, type, bytes);
44
+ this.enqueueRaw(core.getMessageBytes.raw(core.Protocol.ROOM_DATA_BYTES, type, undefined, bytes), options);
45
+ }
42
46
  send(messageOrType, messageOrOptions, options) {
43
47
  core.debugMessage("send(to %s): '%s' -> %O", this.sessionId, messageOrType, messageOrOptions);
44
48
  this.enqueueRaw((messageOrType instanceof schema.Schema)
45
49
  ? core.getMessageBytes[core.Protocol.ROOM_DATA_SCHEMA](messageOrType)
46
- : core.getMessageBytes[core.Protocol.ROOM_DATA](messageOrType, messageOrOptions), options);
50
+ : core.getMessageBytes.raw(core.Protocol.ROOM_DATA, messageOrType, messageOrOptions), options);
47
51
  }
48
52
  enqueueRaw(data, options) {
49
53
  // use room's afterNextPatch queue
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketClient.js","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions, logger, debugMessage } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public readyState: number = ReadyState.OPEN;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %O\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n logger.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":["EventEmitter","ReadyState","ClientState","debugMessage","Schema","getMessageBytes","Protocol","logger"],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketClient.js","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions, logger, debugMessage } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public readyState: number = ReadyState.OPEN;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public sendBytes(type: any, bytes?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send bytes(to %s): '%s' -> %j\", this.sessionId, type, bytes);\n\n this.enqueueRaw(\n getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes),\n options,\n );\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %O\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n logger.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":["EventEmitter","ReadyState","ClientState","debugMessage","getMessageBytes","Protocol","Schema","logger"],"mappings":"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"}
@@ -31,11 +31,15 @@ class uWebSocketClient {
31
31
  this.sessionId = id;
32
32
  ref.on('close', () => this.readyState = ReadyState.CLOSED);
33
33
  }
34
+ sendBytes(type, bytes, options) {
35
+ debugMessage("send bytes(to %s): '%s' -> %j", this.sessionId, type, bytes);
36
+ this.enqueueRaw(getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes), options);
37
+ }
34
38
  send(messageOrType, messageOrOptions, options) {
35
39
  debugMessage("send(to %s): '%s' -> %O", this.sessionId, messageOrType, messageOrOptions);
36
40
  this.enqueueRaw((messageOrType instanceof Schema)
37
41
  ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)
38
- : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions), options);
42
+ : getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions), options);
39
43
  }
40
44
  enqueueRaw(data, options) {
41
45
  // use room's afterNextPatch queue
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketClient.mjs","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions, logger, debugMessage } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public readyState: number = ReadyState.OPEN;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %O\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes[Protocol.ROOM_DATA](messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n logger.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketClient.mjs","sources":["../src/uWebSocketClient.ts"],"sourcesContent":["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, Client, ClientState, ISendOptions, logger, debugMessage } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class uWebSocketWrapper extends EventEmitter {\n constructor(public ws: uWebSockets.WebSocket) {\n super();\n }\n}\n\nexport enum ReadyState {\n CONNECTING = 0,\n OPEN = 1,\n CLOSING = 2,\n CLOSED = 3,\n}\n\nexport class uWebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public readyState: number = ReadyState.OPEN;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n\n constructor(\n public id: string,\n public ref: uWebSocketWrapper,\n ) {\n this.sessionId = id;\n\n ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n public sendBytes(type: any, bytes?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send bytes(to %s): '%s' -> %j\", this.sessionId, type, bytes);\n\n this.enqueueRaw(\n getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes),\n options,\n );\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %O\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n if (this.readyState !== ReadyState.OPEN) {\n logger.warn('trying to send data to inactive client', this.sessionId);\n return;\n }\n\n this.ref.ws.send(new Uint8Array(data), true, false);\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this.ref.ws.end(code, data);\n\n } else {\n this.ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],"names":[],"mappings":"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"}
@@ -127,21 +127,15 @@ class uWebSocketsTransport extends core.Transport {
127
127
  }
128
128
  }
129
129
  registerMatchMakeRequest() {
130
- const headers = {
131
- 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
132
- 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
133
- 'Access-Control-Allow-Origin': '*',
134
- 'Access-Control-Max-Age': 2592000,
135
- // ...
136
- };
137
130
  // TODO: DRY with Server.ts
138
131
  const matchmakeRoute = 'matchmake';
139
132
  const allowedRoomNameChars = /([a-zA-Z_\-0-9]+)/gi;
140
- const writeHeaders = (res) => {
133
+ const writeHeaders = (req, res) => {
141
134
  // skip if aborted
142
135
  if (res.aborted) {
143
136
  return;
144
137
  }
138
+ const headers = Object.assign({}, core.matchMaker.controller.DEFAULT_CORS_HEADERS, core.matchMaker.controller.getCorsHeaders.call(undefined, req));
145
139
  for (const header in headers) {
146
140
  res.writeHeader(header, headers[header].toString());
147
141
  }
@@ -160,14 +154,14 @@ class uWebSocketsTransport extends core.Transport {
160
154
  };
161
155
  this.app.options("/matchmake/*", (res, req) => {
162
156
  res.onAborted(() => onAborted(res));
163
- if (writeHeaders(res)) {
157
+ if (writeHeaders(req, res)) {
164
158
  res.writeStatus("204 No Content");
165
159
  res.end();
166
160
  }
167
161
  });
168
162
  this.app.post("/matchmake/*", (res, req) => {
169
163
  res.onAborted(() => onAborted(res));
170
- writeHeaders(res);
164
+ writeHeaders(req, res);
171
165
  res.writeHeader('Content-Type', 'application/json');
172
166
  const url = req.getUrl();
173
167
  const matchedParams = url.match(allowedRoomNameChars);
@@ -198,7 +192,7 @@ class uWebSocketsTransport extends core.Transport {
198
192
  // });
199
193
  this.app.get("/matchmake/*", async (res, req) => {
200
194
  res.onAborted(() => onAborted(res));
201
- writeHeaders(res);
195
+ writeHeaders(req, res);
202
196
  res.writeHeader('Content-Type', 'application/json');
203
197
  const url = req.getUrl();
204
198
  const matchedParams = url.match(allowedRoomNameChars);
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketsTransport.js","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\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 // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":["Transport","uWebSockets","DummyServer","spliceOne","uWebSocketClient","uWebSocketWrapper","querystring","matchMaker","debugAndPrintError","ErrorCode"],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketsTransport.js","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":["Transport","uWebSockets","DummyServer","spliceOne","uWebSocketClient","uWebSocketWrapper","querystring","matchMaker","debugAndPrintError","ErrorCode"],"mappings":"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"}
@@ -118,21 +118,15 @@ class uWebSocketsTransport extends Transport {
118
118
  }
119
119
  }
120
120
  registerMatchMakeRequest() {
121
- const headers = {
122
- 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
123
- 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
124
- 'Access-Control-Allow-Origin': '*',
125
- 'Access-Control-Max-Age': 2592000,
126
- // ...
127
- };
128
121
  // TODO: DRY with Server.ts
129
122
  const matchmakeRoute = 'matchmake';
130
123
  const allowedRoomNameChars = /([a-zA-Z_\-0-9]+)/gi;
131
- const writeHeaders = (res) => {
124
+ const writeHeaders = (req, res) => {
132
125
  // skip if aborted
133
126
  if (res.aborted) {
134
127
  return;
135
128
  }
129
+ const headers = Object.assign({}, matchMaker.controller.DEFAULT_CORS_HEADERS, matchMaker.controller.getCorsHeaders.call(undefined, req));
136
130
  for (const header in headers) {
137
131
  res.writeHeader(header, headers[header].toString());
138
132
  }
@@ -151,14 +145,14 @@ class uWebSocketsTransport extends Transport {
151
145
  };
152
146
  this.app.options("/matchmake/*", (res, req) => {
153
147
  res.onAborted(() => onAborted(res));
154
- if (writeHeaders(res)) {
148
+ if (writeHeaders(req, res)) {
155
149
  res.writeStatus("204 No Content");
156
150
  res.end();
157
151
  }
158
152
  });
159
153
  this.app.post("/matchmake/*", (res, req) => {
160
154
  res.onAborted(() => onAborted(res));
161
- writeHeaders(res);
155
+ writeHeaders(req, res);
162
156
  res.writeHeader('Content-Type', 'application/json');
163
157
  const url = req.getUrl();
164
158
  const matchedParams = url.match(allowedRoomNameChars);
@@ -189,7 +183,7 @@ class uWebSocketsTransport extends Transport {
189
183
  // });
190
184
  this.app.get("/matchmake/*", async (res, req) => {
191
185
  res.onAborted(() => onAborted(res));
192
- writeHeaders(res);
186
+ writeHeaders(req, res);
193
187
  res.writeHeader('Content-Type', 'application/json');
194
188
  const url = req.getUrl();
195
189
  const matchedParams = url.match(allowedRoomNameChars);
@@ -1 +1 @@
1
- {"version":3,"file":"uWebSocketsTransport.mjs","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\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 // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uWebSocketsTransport.mjs","sources":["../src/uWebSocketsTransport.ts"],"sourcesContent":["import http from 'http';\nimport querystring from 'querystring';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne } from '@colyseus/core';\nimport { uWebSocketClient, uWebSocketWrapper } from './uWebSocketClient';\n\nexport type TransportOptions = Omit<uWebSockets.WebSocketBehavior, \"upgrade\" | \"open\" | \"pong\" | \"close\" | \"message\">;\n\ntype RawWebSocketClient = uWebSockets.WebSocket & {\n headers: {[key: string]: string},\n connection: { remoteAddress: string },\n};\n\nexport class uWebSocketsTransport extends Transport {\n public app: uWebSockets.TemplatedApp;\n\n protected clients: RawWebSocketClient[] = [];\n protected clientWrappers = new WeakMap<RawWebSocketClient, uWebSocketWrapper>();\n\n private _listeningSocket: any;\n\n constructor(options: TransportOptions = {}, appOptions: uWebSockets.AppOptions = {}) {\n super();\n\n this.app = (appOptions.cert_file_name && appOptions.key_file_name)\n ? uWebSockets.SSLApp(appOptions)\n : uWebSockets.App(appOptions);\n\n if (!options.maxBackpressure) {\n options.maxBackpressure = 1024 * 1024;\n }\n\n if (!options.compression) {\n options.compression = uWebSockets.DISABLED;\n }\n\n if (!options.maxPayloadLength) {\n options.maxPayloadLength = 1024 * 1024;\n }\n\n // https://github.com/colyseus/colyseus/issues/458\n // Adding a mock object for Transport.server\n if(!this.server) {\n this.server = new DummyServer();\n }\n\n this.app.ws('/*', {\n ...options,\n\n upgrade: (res, req, context) => {\n // get all headers\n const headers: {[id: string]: string} = {};\n req.forEach((key, value) => headers[key] = value);\n\n /* This immediately calls open handler, you must not use res after this call */\n /* Spell these correctly */\n res.upgrade(\n {\n url: req.getUrl(),\n query: req.getQuery(),\n\n // compatibility with @colyseus/ws-transport\n headers,\n connection: {\n remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString()\n }\n },\n req.getHeader('sec-websocket-key'),\n req.getHeader('sec-websocket-protocol'),\n req.getHeader('sec-websocket-extensions'),\n context\n );\n },\n\n open: async (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n await this.onConnection(ws);\n },\n\n // pong: (ws: RawWebSocketClient) => {\n // ws.pingCount = 0;\n // },\n\n close: (ws: RawWebSocketClient, code: number, message: ArrayBuffer) => {\n // remove from client list\n spliceOne(this.clients, this.clients.indexOf(ws));\n\n const clientWrapper = this.clientWrappers.get(ws);\n if (clientWrapper) {\n this.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n\n message: (ws: RawWebSocketClient, message: ArrayBuffer, isBinary: boolean) => {\n // emit 'close' on wrapper\n this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n },\n\n });\n\n this.registerMatchMakeRequest();\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this.app.listen(port, (listeningSocket: any) => {\n this._listeningSocket = listeningSocket;\n listeningListener?.();\n this.server.emit(\"listening\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n });\n return this;\n }\n\n public shutdown() {\n if (this._listeningSocket) {\n uWebSockets.us_listen_socket_close(this._listeningSocket);\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n const originalRawSend = uWebSocketClient.prototype.raw;\n uWebSocketClient.prototype.raw = function() {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n }\n }\n\n protected async onConnection(rawClient: RawWebSocketClient) {\n const wrapper = new uWebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const query = rawClient.query;\n const url = rawClient.url;\n const searchParams = querystring.parse(query);\n\n const sessionId = searchParams.sessionId as string;\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new uWebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, searchParams.reconnectionToken as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected registerMatchMakeRequest() {\n\n // TODO: DRY with Server.ts\n const matchmakeRoute = 'matchmake';\n const allowedRoomNameChars = /([a-zA-Z_\\-0-9]+)/gi;\n\n const writeHeaders = (req: uWebSockets.HttpRequest, res: uWebSockets.HttpResponse) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n const headers = Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n );\n\n for (const header in headers) {\n res.writeHeader(header, headers[header].toString());\n }\n\n return true;\n }\n\n const writeError = (res: uWebSockets.HttpResponse, error: { code: number, error: string }) => {\n // skip if aborted\n if (res.aborted) { return; }\n\n res.writeStatus(\"406 Not Acceptable\");\n res.end(JSON.stringify(error));\n }\n\n const onAborted = (res: uWebSockets.HttpResponse) => {\n res.aborted = true;\n };\n\n this.app.options(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n if (writeHeaders(req, res)) {\n res.writeStatus(\"204 No Content\");\n res.end();\n }\n });\n\n this.app.post(\"/matchmake/*\", (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchmakeRoute);\n\n // read json body\n this.readJson(res, async (clientOptions) => {\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n try {\n const response = await matchMaker.controller.invokeMethod(method, roomName, clientOptions);\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n\n });\n });\n\n // this.app.any(\"/*\", (res, req) => {\n // res.onAborted(() => onAborted(req));\n // res.writeStatus(\"200 OK\");\n // });\n\n this.app.get(\"/matchmake/*\", async (res, req) => {\n res.onAborted(() => onAborted(res));\n\n writeHeaders(req, res);\n res.writeHeader('Content-Type', 'application/json');\n\n const url = req.getUrl();\n const matchedParams = url.match(allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n try {\n const response = await matchMaker.controller.getAvailableRooms(roomName || '')\n if (!res.aborted) {\n res.writeStatus(\"200 OK\");\n res.end(JSON.stringify(response));\n }\n\n } catch (e) {\n debugAndPrintError(e);\n writeError(res, {\n code: e.code || ErrorCode.MATCHMAKE_UNHANDLED,\n error: e.message\n });\n }\n });\n }\n\n /* Helper function for reading a posted JSON body */\n /* Extracted from https://github.com/uNetworking/uWebSockets.js/blob/master/examples/JsonPost.js */\n private readJson(res: uWebSockets.HttpResponse, cb: (json: any) => void) {\n let buffer: any;\n /* Register data cb */\n res.onData((ab, isLast) => {\n let chunk = Buffer.from(ab);\n if (isLast) {\n let json;\n if (buffer) {\n try {\n // @ts-ignore\n json = JSON.parse(Buffer.concat([buffer, chunk]));\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n } else {\n try {\n // @ts-ignore\n json = JSON.parse(chunk);\n } catch (e) {\n /* res.close calls onAborted */\n res.close();\n cb(undefined);\n return;\n }\n cb(json);\n }\n } else {\n if (buffer) {\n buffer = Buffer.concat([buffer, chunk]);\n } else {\n buffer = Buffer.concat([chunk]);\n }\n }\n });\n }\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@colyseus/uwebsockets-transport",
3
- "version": "0.15.0-preview.0",
3
+ "version": "0.15.0-preview.1",
4
4
  "input": "./src/index.ts",
5
5
  "main": "./build/index.js",
6
6
  "module": "./build/index.mjs",
7
7
  "typings": "./build/index.d.ts",
8
8
  "dependencies": {
9
- "@colyseus/core": "0.15.0-preview.0",
9
+ "@colyseus/core": "^0.15.0-preview.2",
10
10
  "@colyseus/schema": "^2.0.0",
11
11
  "uWebSockets.js": "github:uNetworking/uWebSockets.js#v19.2.0"
12
12
  },
@@ -32,5 +32,5 @@
32
32
  "publishConfig": {
33
33
  "access": "public"
34
34
  },
35
- "gitHead": "24cbffc1e84ef81a397671c5a95fcc3f284c84d4"
35
+ "gitHead": "50c7cac08e2fb7d17aa5bd57c45a7dad9be84722"
36
36
  }