123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- import { BinaryPackChunker, concatArrayBuffers } from "./binaryPackChunker";
- import logger from "../../logger";
- import type { Peer } from "../../peer";
- import { BufferedConnection } from "./BufferedConnection";
- import { SerializationType } from "../../enums";
- import { pack, type Packable, unpack } from "peerjs-js-binarypack";
- export class BinaryPack extends BufferedConnection {
- private readonly chunker = new BinaryPackChunker();
- readonly serialization = SerializationType.Binary;
- private _chunkedData: {
- [id: number]: {
- data: Uint8Array[];
- count: number;
- total: number;
- };
- } = {};
- public override close(options?: { flush?: boolean }) {
- super.close(options);
- this._chunkedData = {};
- }
- constructor(peerId: string, provider: Peer, options: any) {
- super(peerId, provider, options);
- }
- // Handles a DataChannel message.
- protected override _handleDataMessage({ data }: { data: Uint8Array }): void {
- const deserializedData = unpack(data);
- // PeerJS specific message
- const peerData = deserializedData["__peerData"];
- if (peerData) {
- if (peerData.type === "close") {
- this.close();
- return;
- }
- // Chunked data -- piece things back together.
- // @ts-ignore
- this._handleChunk(deserializedData);
- return;
- }
- this.emit("data", deserializedData);
- }
- private _handleChunk(data: {
- __peerData: number;
- n: number;
- total: number;
- data: ArrayBuffer;
- }): void {
- const id = data.__peerData;
- const chunkInfo = this._chunkedData[id] || {
- data: [],
- count: 0,
- total: data.total,
- };
- chunkInfo.data[data.n] = new Uint8Array(data.data);
- chunkInfo.count++;
- this._chunkedData[id] = chunkInfo;
- if (chunkInfo.total === chunkInfo.count) {
- // Clean up before making the recursive call to `_handleDataMessage`.
- delete this._chunkedData[id];
- // We've received all the chunks--time to construct the complete data.
- // const data = new Blob(chunkInfo.data);
- const data = concatArrayBuffers(chunkInfo.data);
- this._handleDataMessage({ data });
- }
- }
- protected override _send(
- data: Packable,
- chunked: boolean,
- ): void | Promise<void> {
- if (data instanceof Blob) {
- return data.arrayBuffer().then((buffer) => {
- this._send(buffer, chunked);
- });
- }
- const blob = pack(data);
- if (!chunked && blob.byteLength > this.chunker.chunkedMTU) {
- this._sendChunks(blob);
- return;
- }
- this._bufferedSend(blob);
- }
- private _sendChunks(blob: ArrayBuffer) {
- const blobs = this.chunker.chunk(blob);
- logger.log(`DC#${this.connectionId} Try to send ${blobs.length} chunks...`);
- for (const blob of blobs) {
- this.send(blob, true);
- }
- }
- }
|