@gleamkit/engine.io 6.6.3
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/LICENSE +19 -0
- package/README.md +603 -0
- package/build/engine.io.d.ts +26 -0
- package/build/engine.io.js +54 -0
- package/build/parser-v3/index.d.ts +94 -0
- package/build/parser-v3/index.js +424 -0
- package/build/parser-v3/utf8.d.ts +14 -0
- package/build/parser-v3/utf8.js +187 -0
- package/build/server.d.ts +267 -0
- package/build/server.js +786 -0
- package/build/socket.d.ts +180 -0
- package/build/socket.js +460 -0
- package/build/transport.d.ts +124 -0
- package/build/transport.js +117 -0
- package/build/transports/index.d.ts +16 -0
- package/build/transports/index.js +23 -0
- package/build/transports/polling-jsonp.d.ts +12 -0
- package/build/transports/polling-jsonp.js +41 -0
- package/build/transports/polling.d.ts +87 -0
- package/build/transports/polling.js +332 -0
- package/build/transports/websocket.d.ts +32 -0
- package/build/transports/websocket.js +94 -0
- package/build/transports/webtransport.d.ts +12 -0
- package/build/transports/webtransport.js +63 -0
- package/build/transports-uws/index.d.ts +7 -0
- package/build/transports-uws/index.js +8 -0
- package/build/transports-uws/polling.d.ts +99 -0
- package/build/transports-uws/polling.js +364 -0
- package/build/transports-uws/websocket.d.ts +32 -0
- package/build/transports-uws/websocket.js +73 -0
- package/build/userver.d.ts +42 -0
- package/build/userver.js +279 -0
- package/package.json +71 -0
- package/wrapper.mjs +10 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Polling = void 0;
|
|
4
|
+
const transport_1 = require("../transport");
|
|
5
|
+
const zlib_1 = require("zlib");
|
|
6
|
+
const accepts = require("accepts");
|
|
7
|
+
const debug_1 = require("debug");
|
|
8
|
+
const debug = (0, debug_1.default)("engine:polling");
|
|
9
|
+
const compressionMethods = {
|
|
10
|
+
gzip: zlib_1.createGzip,
|
|
11
|
+
deflate: zlib_1.createDeflate,
|
|
12
|
+
};
|
|
13
|
+
class Polling extends transport_1.Transport {
|
|
14
|
+
/**
|
|
15
|
+
* HTTP polling constructor.
|
|
16
|
+
*/
|
|
17
|
+
constructor(req) {
|
|
18
|
+
super(req);
|
|
19
|
+
this.closeTimeout = 30 * 1000;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Transport name
|
|
23
|
+
*/
|
|
24
|
+
get name() {
|
|
25
|
+
return "polling";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Overrides onRequest.
|
|
29
|
+
*
|
|
30
|
+
* @param {EngineRequest} req
|
|
31
|
+
* @package
|
|
32
|
+
*/
|
|
33
|
+
onRequest(req) {
|
|
34
|
+
const res = req.res;
|
|
35
|
+
// remove the reference to the ServerResponse object (as the first request of the session is kept in memory by default)
|
|
36
|
+
req.res = null;
|
|
37
|
+
if ("GET" === req.method) {
|
|
38
|
+
this.onPollRequest(req, res);
|
|
39
|
+
}
|
|
40
|
+
else if ("POST" === req.method) {
|
|
41
|
+
this.onDataRequest(req, res);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
res.writeHead(500);
|
|
45
|
+
res.end();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The client sends a request awaiting for us to send data.
|
|
50
|
+
*
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
onPollRequest(req, res) {
|
|
54
|
+
if (this.req) {
|
|
55
|
+
debug("request overlap");
|
|
56
|
+
// assert: this.res, '.req and .res should be (un)set together'
|
|
57
|
+
this.onError("overlap from client");
|
|
58
|
+
res.writeHead(400);
|
|
59
|
+
res.end();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
debug("setting request");
|
|
63
|
+
this.req = req;
|
|
64
|
+
this.res = res;
|
|
65
|
+
const onClose = () => {
|
|
66
|
+
this.onError("poll connection closed prematurely");
|
|
67
|
+
};
|
|
68
|
+
const cleanup = () => {
|
|
69
|
+
req.removeListener("close", onClose);
|
|
70
|
+
this.req = this.res = null;
|
|
71
|
+
};
|
|
72
|
+
req.cleanup = cleanup;
|
|
73
|
+
req.on("close", onClose);
|
|
74
|
+
this.writable = true;
|
|
75
|
+
this.emit("ready");
|
|
76
|
+
// if we're still writable but had a pending close, trigger an empty send
|
|
77
|
+
if (this.writable && this.shouldClose) {
|
|
78
|
+
debug("triggering empty send to append close packet");
|
|
79
|
+
this.send([{ type: "noop" }]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The client sends a request with data.
|
|
84
|
+
*
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
onDataRequest(req, res) {
|
|
88
|
+
if (this.dataReq) {
|
|
89
|
+
// assert: this.dataRes, '.dataReq and .dataRes should be (un)set together'
|
|
90
|
+
this.onError("data request overlap from client");
|
|
91
|
+
res.writeHead(400);
|
|
92
|
+
res.end();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const isBinary = "application/octet-stream" === req.headers["content-type"];
|
|
96
|
+
if (isBinary && this.protocol === 4) {
|
|
97
|
+
return this.onError("invalid content");
|
|
98
|
+
}
|
|
99
|
+
this.dataReq = req;
|
|
100
|
+
this.dataRes = res;
|
|
101
|
+
let chunks = isBinary ? Buffer.concat([]) : "";
|
|
102
|
+
const cleanup = () => {
|
|
103
|
+
req.removeListener("data", onData);
|
|
104
|
+
req.removeListener("end", onEnd);
|
|
105
|
+
req.removeListener("close", onClose);
|
|
106
|
+
this.dataReq = this.dataRes = chunks = null;
|
|
107
|
+
};
|
|
108
|
+
const onClose = () => {
|
|
109
|
+
cleanup();
|
|
110
|
+
this.onError("data request connection closed prematurely");
|
|
111
|
+
};
|
|
112
|
+
const onData = (data) => {
|
|
113
|
+
let contentLength;
|
|
114
|
+
if (isBinary) {
|
|
115
|
+
chunks = Buffer.concat([chunks, data]);
|
|
116
|
+
contentLength = chunks.length;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
chunks += data;
|
|
120
|
+
contentLength = Buffer.byteLength(chunks);
|
|
121
|
+
}
|
|
122
|
+
if (contentLength > this.maxHttpBufferSize) {
|
|
123
|
+
res.writeHead(413).end();
|
|
124
|
+
cleanup();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const onEnd = () => {
|
|
128
|
+
this.onData(chunks);
|
|
129
|
+
const headers = {
|
|
130
|
+
// text/html is required instead of text/plain to avoid an
|
|
131
|
+
// unwanted download dialog on certain user-agents (GH-43)
|
|
132
|
+
"Content-Type": "text/html",
|
|
133
|
+
"Content-Length": "2",
|
|
134
|
+
};
|
|
135
|
+
res.writeHead(200, this.headers(req, headers));
|
|
136
|
+
res.end("ok");
|
|
137
|
+
cleanup();
|
|
138
|
+
};
|
|
139
|
+
req.on("close", onClose);
|
|
140
|
+
if (!isBinary)
|
|
141
|
+
req.setEncoding("utf8");
|
|
142
|
+
req.on("data", onData);
|
|
143
|
+
req.on("end", onEnd);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Processes the incoming data payload.
|
|
147
|
+
*
|
|
148
|
+
* @param data - encoded payload
|
|
149
|
+
* @protected
|
|
150
|
+
*/
|
|
151
|
+
onData(data) {
|
|
152
|
+
debug('received "%s"', data);
|
|
153
|
+
const callback = (packet) => {
|
|
154
|
+
if ("close" === packet.type) {
|
|
155
|
+
debug("got xhr close packet");
|
|
156
|
+
this.onClose();
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
this.onPacket(packet);
|
|
160
|
+
};
|
|
161
|
+
if (this.protocol === 3) {
|
|
162
|
+
this.parser.decodePayload(data, callback);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
this.parser.decodePayload(data).forEach(callback);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Overrides onClose.
|
|
170
|
+
*
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
onClose() {
|
|
174
|
+
if (this.writable) {
|
|
175
|
+
// close pending poll request
|
|
176
|
+
this.send([{ type: "noop" }]);
|
|
177
|
+
}
|
|
178
|
+
super.onClose();
|
|
179
|
+
}
|
|
180
|
+
send(packets) {
|
|
181
|
+
this.writable = false;
|
|
182
|
+
if (this.shouldClose) {
|
|
183
|
+
debug("appending close packet to payload");
|
|
184
|
+
packets.push({ type: "close" });
|
|
185
|
+
this.shouldClose();
|
|
186
|
+
this.shouldClose = null;
|
|
187
|
+
}
|
|
188
|
+
const doWrite = (data) => {
|
|
189
|
+
const compress = packets.some((packet) => {
|
|
190
|
+
return packet.options && packet.options.compress;
|
|
191
|
+
});
|
|
192
|
+
this.write(data, { compress });
|
|
193
|
+
};
|
|
194
|
+
if (this.protocol === 3) {
|
|
195
|
+
this.parser.encodePayload(packets, this.supportsBinary, doWrite);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this.parser.encodePayload(packets, doWrite);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Writes data as response to poll request.
|
|
203
|
+
*
|
|
204
|
+
* @param {String} data
|
|
205
|
+
* @param {Object} options
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
write(data, options) {
|
|
209
|
+
debug('writing "%s"', data);
|
|
210
|
+
this.doWrite(data, options, () => {
|
|
211
|
+
this.req.cleanup();
|
|
212
|
+
this.emit("drain");
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Performs the write.
|
|
217
|
+
*
|
|
218
|
+
* @protected
|
|
219
|
+
*/
|
|
220
|
+
doWrite(data, options, callback) {
|
|
221
|
+
// explicit UTF-8 is required for pages not served under utf
|
|
222
|
+
const isString = typeof data === "string";
|
|
223
|
+
const contentType = isString
|
|
224
|
+
? "text/plain; charset=UTF-8"
|
|
225
|
+
: "application/octet-stream";
|
|
226
|
+
const headers = {
|
|
227
|
+
"Content-Type": contentType,
|
|
228
|
+
};
|
|
229
|
+
const respond = (data) => {
|
|
230
|
+
headers["Content-Length"] =
|
|
231
|
+
"string" === typeof data ? Buffer.byteLength(data) : data.length;
|
|
232
|
+
this.res.writeHead(200, this.headers(this.req, headers));
|
|
233
|
+
this.res.end(data);
|
|
234
|
+
callback();
|
|
235
|
+
};
|
|
236
|
+
if (!this.httpCompression || !options.compress) {
|
|
237
|
+
respond(data);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const len = isString ? Buffer.byteLength(data) : data.length;
|
|
241
|
+
if (len < this.httpCompression.threshold) {
|
|
242
|
+
respond(data);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const encoding = accepts(this.req).encodings(["gzip", "deflate"]);
|
|
246
|
+
if (!encoding) {
|
|
247
|
+
respond(data);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
this.compress(data, encoding, (err, data) => {
|
|
251
|
+
if (err) {
|
|
252
|
+
this.res.writeHead(500);
|
|
253
|
+
this.res.end();
|
|
254
|
+
callback(err);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
headers["Content-Encoding"] = encoding;
|
|
258
|
+
respond(data);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Compresses data.
|
|
263
|
+
*
|
|
264
|
+
* @private
|
|
265
|
+
*/
|
|
266
|
+
compress(data, encoding, callback) {
|
|
267
|
+
debug("compressing");
|
|
268
|
+
const buffers = [];
|
|
269
|
+
let nread = 0;
|
|
270
|
+
compressionMethods[encoding](this.httpCompression)
|
|
271
|
+
.on("error", callback)
|
|
272
|
+
.on("data", function (chunk) {
|
|
273
|
+
buffers.push(chunk);
|
|
274
|
+
nread += chunk.length;
|
|
275
|
+
})
|
|
276
|
+
.on("end", function () {
|
|
277
|
+
callback(null, Buffer.concat(buffers, nread));
|
|
278
|
+
})
|
|
279
|
+
.end(data);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Closes the transport.
|
|
283
|
+
*
|
|
284
|
+
* @private
|
|
285
|
+
*/
|
|
286
|
+
doClose(fn) {
|
|
287
|
+
debug("closing");
|
|
288
|
+
let closeTimeoutTimer;
|
|
289
|
+
if (this.dataReq) {
|
|
290
|
+
debug("aborting ongoing data request");
|
|
291
|
+
this.dataReq.destroy();
|
|
292
|
+
}
|
|
293
|
+
const onClose = () => {
|
|
294
|
+
clearTimeout(closeTimeoutTimer);
|
|
295
|
+
fn();
|
|
296
|
+
this.onClose();
|
|
297
|
+
};
|
|
298
|
+
if (this.writable) {
|
|
299
|
+
debug("transport writable - closing right away");
|
|
300
|
+
this.send([{ type: "close" }]);
|
|
301
|
+
onClose();
|
|
302
|
+
}
|
|
303
|
+
else if (this.discarded) {
|
|
304
|
+
debug("transport discarded - closing right away");
|
|
305
|
+
onClose();
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
debug("transport not writable - buffering orderly close");
|
|
309
|
+
this.shouldClose = onClose;
|
|
310
|
+
closeTimeoutTimer = setTimeout(onClose, this.closeTimeout);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Returns headers for a response.
|
|
315
|
+
*
|
|
316
|
+
* @param {http.IncomingMessage} req
|
|
317
|
+
* @param {Object} headers - extra headers
|
|
318
|
+
* @private
|
|
319
|
+
*/
|
|
320
|
+
headers(req, headers = {}) {
|
|
321
|
+
// prevent XSS warnings on IE
|
|
322
|
+
// https://github.com/LearnBoost/socket.io/pull/1333
|
|
323
|
+
const ua = req.headers["user-agent"];
|
|
324
|
+
if (ua && (~ua.indexOf(";MSIE") || ~ua.indexOf("Trident/"))) {
|
|
325
|
+
headers["X-XSS-Protection"] = "0";
|
|
326
|
+
}
|
|
327
|
+
headers["cache-control"] = "no-store";
|
|
328
|
+
this.emit("headers", headers, req);
|
|
329
|
+
return headers;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
exports.Polling = Polling;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { EngineRequest, Transport } from "../transport";
|
|
2
|
+
import type { Packet } from "engine.io-parser";
|
|
3
|
+
export declare class WebSocket extends Transport {
|
|
4
|
+
protected perMessageDeflate: any;
|
|
5
|
+
private socket;
|
|
6
|
+
/**
|
|
7
|
+
* WebSocket transport
|
|
8
|
+
*
|
|
9
|
+
* @param {EngineRequest} req
|
|
10
|
+
*/
|
|
11
|
+
constructor(req: EngineRequest);
|
|
12
|
+
/**
|
|
13
|
+
* Transport name
|
|
14
|
+
*/
|
|
15
|
+
get name(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Advertise upgrade support.
|
|
18
|
+
*/
|
|
19
|
+
get handlesUpgrades(): boolean;
|
|
20
|
+
send(packets: Packet[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the encoding of the WebSocket frame can be skipped.
|
|
23
|
+
* @param packet
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
private _canSendPreEncodedFrame;
|
|
27
|
+
private _doSend;
|
|
28
|
+
private _doSendLast;
|
|
29
|
+
private _onSent;
|
|
30
|
+
private _onSentLast;
|
|
31
|
+
doClose(fn?: () => void): void;
|
|
32
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebSocket = void 0;
|
|
4
|
+
const transport_1 = require("../transport");
|
|
5
|
+
const debug_1 = require("debug");
|
|
6
|
+
const debug = (0, debug_1.default)("engine:ws");
|
|
7
|
+
class WebSocket extends transport_1.Transport {
|
|
8
|
+
/**
|
|
9
|
+
* WebSocket transport
|
|
10
|
+
*
|
|
11
|
+
* @param {EngineRequest} req
|
|
12
|
+
*/
|
|
13
|
+
constructor(req) {
|
|
14
|
+
super(req);
|
|
15
|
+
this._doSend = (data) => {
|
|
16
|
+
this.socket.send(data, this._onSent);
|
|
17
|
+
};
|
|
18
|
+
this._doSendLast = (data) => {
|
|
19
|
+
this.socket.send(data, this._onSentLast);
|
|
20
|
+
};
|
|
21
|
+
this._onSent = (err) => {
|
|
22
|
+
if (err) {
|
|
23
|
+
this.onError("write error", err.stack);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
this._onSentLast = (err) => {
|
|
27
|
+
if (err) {
|
|
28
|
+
this.onError("write error", err.stack);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
this.emit("drain");
|
|
32
|
+
this.writable = true;
|
|
33
|
+
this.emit("ready");
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
this.socket = req.websocket;
|
|
37
|
+
this.socket.on("message", (data, isBinary) => {
|
|
38
|
+
const message = isBinary ? data : data.toString();
|
|
39
|
+
debug('received "%s"', message);
|
|
40
|
+
super.onData(message);
|
|
41
|
+
});
|
|
42
|
+
this.socket.once("close", this.onClose.bind(this));
|
|
43
|
+
this.socket.on("error", this.onError.bind(this));
|
|
44
|
+
this.writable = true;
|
|
45
|
+
this.perMessageDeflate = null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Transport name
|
|
49
|
+
*/
|
|
50
|
+
get name() {
|
|
51
|
+
return "websocket";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Advertise upgrade support.
|
|
55
|
+
*/
|
|
56
|
+
get handlesUpgrades() {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
send(packets) {
|
|
60
|
+
this.writable = false;
|
|
61
|
+
for (let i = 0; i < packets.length; i++) {
|
|
62
|
+
const packet = packets[i];
|
|
63
|
+
const isLast = i + 1 === packets.length;
|
|
64
|
+
if (this._canSendPreEncodedFrame(packet)) {
|
|
65
|
+
// the WebSocket frame was computed with WebSocket.Sender.frame()
|
|
66
|
+
// see https://github.com/websockets/ws/issues/617#issuecomment-283002469
|
|
67
|
+
this.socket._sender.sendFrame(
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
packet.options.wsPreEncodedFrame, isLast ? this._onSentLast : this._onSent);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.parser.encodePacket(packet, this.supportsBinary, isLast ? this._doSendLast : this._doSend);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether the encoding of the WebSocket frame can be skipped.
|
|
78
|
+
* @param packet
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
_canSendPreEncodedFrame(packet) {
|
|
82
|
+
var _a, _b, _c;
|
|
83
|
+
return (!this.perMessageDeflate &&
|
|
84
|
+
typeof ((_b = (_a = this.socket) === null || _a === void 0 ? void 0 : _a._sender) === null || _b === void 0 ? void 0 : _b.sendFrame) === "function" &&
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
((_c = packet.options) === null || _c === void 0 ? void 0 : _c.wsPreEncodedFrame) !== undefined);
|
|
87
|
+
}
|
|
88
|
+
doClose(fn) {
|
|
89
|
+
debug("closing");
|
|
90
|
+
this.socket.close();
|
|
91
|
+
fn && fn();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.WebSocket = WebSocket;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Transport } from "../transport";
|
|
2
|
+
/**
|
|
3
|
+
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API
|
|
4
|
+
*/
|
|
5
|
+
export declare class WebTransport extends Transport {
|
|
6
|
+
private readonly session;
|
|
7
|
+
private readonly writer;
|
|
8
|
+
constructor(session: any, stream: any, reader: any);
|
|
9
|
+
get name(): string;
|
|
10
|
+
send(packets: any): Promise<void>;
|
|
11
|
+
doClose(fn: any): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebTransport = void 0;
|
|
4
|
+
const transport_1 = require("../transport");
|
|
5
|
+
const debug_1 = require("debug");
|
|
6
|
+
const engine_io_parser_1 = require("engine.io-parser");
|
|
7
|
+
const debug = (0, debug_1.default)("engine:webtransport");
|
|
8
|
+
/**
|
|
9
|
+
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API
|
|
10
|
+
*/
|
|
11
|
+
class WebTransport extends transport_1.Transport {
|
|
12
|
+
constructor(session, stream, reader) {
|
|
13
|
+
super({ _query: { EIO: "4" } });
|
|
14
|
+
this.session = session;
|
|
15
|
+
const transformStream = (0, engine_io_parser_1.createPacketEncoderStream)();
|
|
16
|
+
transformStream.readable.pipeTo(stream.writable).catch(() => {
|
|
17
|
+
debug("the stream was closed");
|
|
18
|
+
});
|
|
19
|
+
this.writer = transformStream.writable.getWriter();
|
|
20
|
+
(async () => {
|
|
21
|
+
try {
|
|
22
|
+
while (true) {
|
|
23
|
+
const { value, done } = await reader.read();
|
|
24
|
+
if (done) {
|
|
25
|
+
debug("session is closed");
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
debug("received chunk: %o", value);
|
|
29
|
+
this.onPacket(value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
debug("error while reading: %s", e.message);
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
session.closed.then(() => this.onClose());
|
|
37
|
+
this.writable = true;
|
|
38
|
+
}
|
|
39
|
+
get name() {
|
|
40
|
+
return "webtransport";
|
|
41
|
+
}
|
|
42
|
+
async send(packets) {
|
|
43
|
+
this.writable = false;
|
|
44
|
+
try {
|
|
45
|
+
for (let i = 0; i < packets.length; i++) {
|
|
46
|
+
const packet = packets[i];
|
|
47
|
+
await this.writer.write(packet);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
debug("error while writing: %s", e.message);
|
|
52
|
+
}
|
|
53
|
+
this.emit("drain");
|
|
54
|
+
this.writable = true;
|
|
55
|
+
this.emit("ready");
|
|
56
|
+
}
|
|
57
|
+
doClose(fn) {
|
|
58
|
+
debug("closing WebTransport session");
|
|
59
|
+
this.session.close();
|
|
60
|
+
fn && fn();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.WebTransport = WebTransport;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Transport } from "../transport";
|
|
2
|
+
export declare class Polling extends Transport {
|
|
3
|
+
maxHttpBufferSize: number;
|
|
4
|
+
httpCompression: any;
|
|
5
|
+
private req;
|
|
6
|
+
private res;
|
|
7
|
+
private dataReq;
|
|
8
|
+
private dataRes;
|
|
9
|
+
private shouldClose;
|
|
10
|
+
private readonly closeTimeout;
|
|
11
|
+
/**
|
|
12
|
+
* HTTP polling constructor.
|
|
13
|
+
*/
|
|
14
|
+
constructor(req: any);
|
|
15
|
+
/**
|
|
16
|
+
* Transport name
|
|
17
|
+
*/
|
|
18
|
+
get name(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Overrides onRequest.
|
|
21
|
+
*
|
|
22
|
+
* @param req
|
|
23
|
+
*
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
onRequest(req: any): void;
|
|
27
|
+
/**
|
|
28
|
+
* The client sends a request awaiting for us to send data.
|
|
29
|
+
*
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
onPollRequest(req: any, res: any): void;
|
|
33
|
+
/**
|
|
34
|
+
* The client sends a request with data.
|
|
35
|
+
*
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
onDataRequest(req: any, res: any): void;
|
|
39
|
+
/**
|
|
40
|
+
* Cleanup request.
|
|
41
|
+
*
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
private onDataRequestCleanup;
|
|
45
|
+
/**
|
|
46
|
+
* Processes the incoming data payload.
|
|
47
|
+
*
|
|
48
|
+
* @param {String} encoded payload
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
onData(data: any): void;
|
|
52
|
+
/**
|
|
53
|
+
* Overrides onClose.
|
|
54
|
+
*
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
onClose(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Writes a packet payload.
|
|
60
|
+
*
|
|
61
|
+
* @param {Object} packet
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
send(packets: any): void;
|
|
65
|
+
/**
|
|
66
|
+
* Writes data as response to poll request.
|
|
67
|
+
*
|
|
68
|
+
* @param {String} data
|
|
69
|
+
* @param {Object} options
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
write(data: any, options: any): void;
|
|
73
|
+
/**
|
|
74
|
+
* Performs the write.
|
|
75
|
+
*
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
doWrite(data: any, options: any, callback: any): void;
|
|
79
|
+
/**
|
|
80
|
+
* Compresses data.
|
|
81
|
+
*
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
compress(data: any, encoding: any, callback: any): void;
|
|
85
|
+
/**
|
|
86
|
+
* Closes the transport.
|
|
87
|
+
*
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
doClose(fn: any): void;
|
|
91
|
+
/**
|
|
92
|
+
* Returns headers for a response.
|
|
93
|
+
*
|
|
94
|
+
* @param req - request
|
|
95
|
+
* @param {Object} extra headers
|
|
96
|
+
* @private
|
|
97
|
+
*/
|
|
98
|
+
headers(req: any, headers: any): any;
|
|
99
|
+
}
|