|
1 | 1 | import { transports } from "./transports/index.js";
|
2 |
| -import { installTimerFunctions } from "./util.js"; |
| 2 | +import { installTimerFunctions, byteLength } from "./util.js"; |
3 | 3 | import parseqs from "parseqs";
|
4 | 4 | import parseuri from "parseuri";
|
5 | 5 | import debugModule from "debug"; // debug()
|
@@ -249,6 +249,7 @@ export class Socket extends Emitter<{}, {}, SocketReservedEvents> {
|
249 | 249 | private clearTimeoutFn: typeof clearTimeout;
|
250 | 250 | private offlineEventListener;
|
251 | 251 | private upgrading: boolean;
|
| 252 | + private maxPayload?: number; |
252 | 253 |
|
253 | 254 | private readonly opts: Partial<SocketOptions>;
|
254 | 255 | private readonly secure: boolean;
|
@@ -676,6 +677,7 @@ export class Socket extends Emitter<{}, {}, SocketReservedEvents> {
|
676 | 677 | this.upgrades = this.filterUpgrades(data.upgrades);
|
677 | 678 | this.pingInterval = data.pingInterval;
|
678 | 679 | this.pingTimeout = data.pingTimeout;
|
| 680 | + this.maxPayload = data.maxPayload; |
679 | 681 | this.onOpen();
|
680 | 682 | // In case open handler closes socket
|
681 | 683 | if ("closed" === this.readyState) return;
|
@@ -729,15 +731,46 @@ export class Socket extends Emitter<{}, {}, SocketReservedEvents> {
|
729 | 731 | !this.upgrading &&
|
730 | 732 | this.writeBuffer.length
|
731 | 733 | ) {
|
732 |
| - debug("flushing %d packets in socket", this.writeBuffer.length); |
733 |
| - this.transport.send(this.writeBuffer); |
| 734 | + const packets = this.getWritablePackets(); |
| 735 | + debug("flushing %d packets in socket", packets.length); |
| 736 | + this.transport.send(packets); |
734 | 737 | // keep track of current length of writeBuffer
|
735 | 738 | // splice writeBuffer and callbackBuffer on `drain`
|
736 |
| - this.prevBufferLen = this.writeBuffer.length; |
| 739 | + this.prevBufferLen = packets.length; |
737 | 740 | this.emitReserved("flush");
|
738 | 741 | }
|
739 | 742 | }
|
740 | 743 |
|
| 744 | + /** |
| 745 | + * Ensure the encoded size of the writeBuffer is below the maxPayload value sent by the server (only for HTTP |
| 746 | + * long-polling) |
| 747 | + * |
| 748 | + * @private |
| 749 | + */ |
| 750 | + private getWritablePackets() { |
| 751 | + const shouldCheckPayloadSize = |
| 752 | + this.maxPayload && |
| 753 | + this.transport.name === "polling" && |
| 754 | + this.writeBuffer.length > 1; |
| 755 | + if (!shouldCheckPayloadSize) { |
| 756 | + return this.writeBuffer; |
| 757 | + } |
| 758 | + let payloadSize = 1; // first packet type |
| 759 | + for (let i = 0; i < this.writeBuffer.length; i++) { |
| 760 | + const data = this.writeBuffer[i].data; |
| 761 | + if (data) { |
| 762 | + payloadSize += byteLength(data); |
| 763 | + } |
| 764 | + if (i > 0 && payloadSize > this.maxPayload) { |
| 765 | + debug("only send %d out of %d packets", i, this.writeBuffer.length); |
| 766 | + return this.writeBuffer.slice(0, i); |
| 767 | + } |
| 768 | + payloadSize += 2; // separator + packet type |
| 769 | + } |
| 770 | + debug("payload size is %d (max: %d)", payloadSize, this.maxPayload); |
| 771 | + return this.writeBuffer; |
| 772 | + } |
| 773 | + |
741 | 774 | /**
|
742 | 775 | * Sends a message.
|
743 | 776 | *
|
|
0 commit comments