소스 검색

fix(datachannel): sending order is now preserved correctly

Closes #746
Jonas Gloning 2 년 전
부모
커밋
18d491a83d
4개의 변경된 파일46개의 추가작업 그리고 29개의 파일을 삭제
  1. 14 15
      lib/dataconnection.ts
  2. 17 6
      lib/util.ts
  3. 14 7
      package-lock.json
  4. 1 1
      package.json

+ 14 - 15
lib/dataconnection.ts

@@ -1,4 +1,4 @@
-import { util } from "./util";
+import { concatArrayBuffers, util } from "./util";
 import logger from "./logger";
 import { Negotiator } from "./negotiator";
 import { ConnectionType, SerializationType, ServerMessageType } from "./enums";
@@ -45,7 +45,7 @@ export class DataConnection
 	private _buffering = false;
 	private _chunkedData: {
 		[id: number]: {
-			data: Blob[];
+			data: Uint8Array[];
 			count: number;
 			total: number;
 		};
@@ -168,7 +168,7 @@ export class DataConnection
 		__peerData: number;
 		n: number;
 		total: number;
-		data: Blob;
+		data: ArrayBuffer;
 	}): void {
 		const id = data.__peerData;
 		const chunkInfo = this._chunkedData[id] || {
@@ -177,7 +177,7 @@ export class DataConnection
 			total: data.total,
 		};
 
-		chunkInfo.data[data.n] = data.data;
+		chunkInfo.data[data.n] = new Uint8Array(data.data);
 		chunkInfo.count++;
 		this._chunkedData[id] = chunkInfo;
 
@@ -186,8 +186,8 @@ export class DataConnection
 			delete this._chunkedData[id];
 
 			// We've received all the chunks--time to construct the complete data.
-			const data = new Blob(chunkInfo.data);
-			this._handleDataMessage({ data });
+			const data = concatArrayBuffers(chunkInfo.data);
+			this.emit("data", util.unpack(data));
 		}
 	}
 
@@ -246,6 +246,11 @@ export class DataConnection
 			return;
 		}
 
+		if (data instanceof Blob) {
+			data.arrayBuffer().then((ab) => this.send(ab));
+			return;
+		}
+
 		if (this.serialization === SerializationType.JSON) {
 			this._bufferedSend(this.stringify(data));
 		} else if (
@@ -254,18 +259,12 @@ export class DataConnection
 		) {
 			const blob = util.pack(data);
 
-			if (!chunked && blob.size > util.chunkedMTU) {
+			if (!chunked && blob.byteLength > util.chunkedMTU) {
 				this._sendChunks(blob);
 				return;
 			}
 
-			if (!util.supports.binaryBlob) {
-				// We only do this if we really need to (e.g. blobs are not supported),
-				// because this conversion is costly.
-				this._encodingQueue.enque(blob);
-			} else {
-				this._bufferedSend(blob);
-			}
+			this._bufferedSend(blob);
 		} else {
 			this._bufferedSend(data);
 		}
@@ -327,7 +326,7 @@ export class DataConnection
 		}
 	}
 
-	private _sendChunks(blob: Blob): void {
+	private _sendChunks(blob: ArrayBuffer): void {
 		const blobs = util.chunk(blob);
 		logger.log(`DC#${this.connectionId} Try to send ${blobs.length} chunks...`);
 

+ 17 - 6
lib/util.ts

@@ -1,6 +1,4 @@
-// Types aren’t accurate
-//@ts-ignore
-import BinaryPack from "peerjs-js-binarypack";
+import * as BinaryPack from "peerjs-js-binarypack";
 import { Supports } from "./supports";
 
 export interface UtilSupportsObj {
@@ -105,10 +103,10 @@ class Util {
 	private _dataCount: number = 1;
 
 	chunk(
-		blob: Blob,
-	): { __peerData: number; n: number; total: number; data: Blob }[] {
+		blob: ArrayBuffer,
+	): { __peerData: number; n: number; total: number; data: ArrayBuffer }[] {
 		const chunks = [];
-		const size = blob.size;
+		const size = blob.byteLength;
 		const total = Math.ceil(size / util.chunkedMTU);
 
 		let index = 0;
@@ -172,3 +170,16 @@ class Util {
 	}
 }
 export const util = new Util();
+export function concatArrayBuffers(bufs: Uint8Array[]) {
+	let size = 0;
+	for (const buf of bufs) {
+		size += buf.byteLength;
+	}
+	const result = new Uint8Array(size);
+	let offset = 0;
+	for (const buf of bufs) {
+		result.set(buf, offset);
+		offset += buf.byteLength;
+	}
+	return result;
+}

+ 14 - 7
package-lock.json

@@ -11,7 +11,7 @@
 			"dependencies": {
 				"@swc/helpers": "^0.4.0",
 				"eventemitter3": "^4.0.7",
-				"peerjs-js-binarypack": "1.0.1",
+				"peerjs-js-binarypack": "^2.0.0-rc.1",
 				"webrtc-adapter": "^8.0.0"
 			},
 			"devDependencies": {
@@ -8073,9 +8073,16 @@
 			}
 		},
 		"node_modules/peerjs-js-binarypack": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz",
-			"integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg=="
+			"version": "2.0.0-rc.1",
+			"resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-2.0.0-rc.1.tgz",
+			"integrity": "sha512-HW0ImWx9dACfwSc9TaHAWOFMmKnZsZycN3BnO5FOcalWMUc2V3IxyrjwLFDCQT2JRoBDN3Pi5byLHX5cRZR9OQ==",
+			"engines": {
+				"node": ">= 14.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/peer"
+			}
 		},
 		"node_modules/picocolors": {
 			"version": "1.0.0",
@@ -15598,9 +15605,9 @@
 			"dev": true
 		},
 		"peerjs-js-binarypack": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz",
-			"integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg=="
+			"version": "2.0.0-rc.1",
+			"resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-2.0.0-rc.1.tgz",
+			"integrity": "sha512-HW0ImWx9dACfwSc9TaHAWOFMmKnZsZycN3BnO5FOcalWMUc2V3IxyrjwLFDCQT2JRoBDN3Pi5byLHX5cRZR9OQ=="
 		},
 		"picocolors": {
 			"version": "1.0.0",

+ 1 - 1
package.json

@@ -184,7 +184,7 @@
 	"dependencies": {
 		"@swc/helpers": "^0.4.0",
 		"eventemitter3": "^4.0.7",
-		"peerjs-js-binarypack": "1.0.1",
+		"peerjs-js-binarypack": "^2.0.0-rc.1",
 		"webrtc-adapter": "^8.0.0"
 	}
 }