fix:Try to fix the problem of incomplete file size in resumable download
This commit is contained in:
@@ -13,7 +13,7 @@ import type { Messages } from "@/types/messages";
|
||||
import { useFileTransferStore } from "@/stores/fileTransferStore";
|
||||
import { supportsAutoDownload } from "@/lib/browserUtils";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
|
||||
function formatFolderDis(template: string, num: number, size: string) {
|
||||
return template.replace("{num}", num.toString()).replace("{size}", size);
|
||||
@@ -261,7 +261,7 @@ const FileListDisplay: React.FC<FileListDisplayProps> = ({
|
||||
|
||||
if (isAutoDownloadSupported) {
|
||||
// Browsers that support automatic downloads like Chrome: Download directly
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[Download Debug] Auto-downloading file: ${item.name}`
|
||||
);
|
||||
@@ -269,7 +269,7 @@ const FileListDisplay: React.FC<FileListDisplayProps> = ({
|
||||
onDownload(item);
|
||||
} else {
|
||||
// Non-Chrome browsers: Set to save status, wait for user manual click
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[Download Debug] Setting pendingSave for non-Chrome browser: ${item.name}`
|
||||
);
|
||||
@@ -280,7 +280,7 @@ const FileListDisplay: React.FC<FileListDisplayProps> = ({
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`Skipping download logic - isSaveToDisk: ${isSaveToDisk}, onDownload: ${!!onDownload}`
|
||||
);
|
||||
|
||||
+235
-67
@@ -22,7 +22,7 @@ import {
|
||||
EmbeddedChunkMeta,
|
||||
} from "@/types/webrtc";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 Strict Sequential Buffering Writer - Optimizes large file disk I/O performance
|
||||
*/
|
||||
@@ -40,6 +40,18 @@ class SequencedDiskWriter {
|
||||
|
||||
/**\n * Write a chunk, automatically managing order and buffering\n */
|
||||
async writeChunk(chunkIndex: number, chunk: ArrayBuffer): Promise<void> {
|
||||
// 🔍 调试writeChunk调用
|
||||
if (
|
||||
developmentEnv === "development" &&
|
||||
(chunkIndex <= 5 || chunkIndex === this.nextWriteIndex)
|
||||
) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-RESUME] 🎯 WriteChunk called - received:${chunkIndex}, expected:${
|
||||
this.nextWriteIndex
|
||||
}, match:${chunkIndex === this.nextWriteIndex}`
|
||||
);
|
||||
}
|
||||
|
||||
// 1. If it is the expected next chunk, write immediately
|
||||
if (chunkIndex === this.nextWriteIndex) {
|
||||
await this.flushSequentialChunks(chunk);
|
||||
@@ -50,26 +62,26 @@ class SequencedDiskWriter {
|
||||
if (chunkIndex > this.nextWriteIndex) {
|
||||
if (this.writeQueue.size < this.maxBufferSize) {
|
||||
this.writeQueue.set(chunkIndex, chunk);
|
||||
if (developmentEnv === "true") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📦 BUFFERED chunk #${chunkIndex} (waiting for #${this.nextWriteIndex}), queue: ${this.writeQueue.size}/${this.maxBufferSize}`
|
||||
);
|
||||
}
|
||||
// if (developmentEnv === "development") {
|
||||
// postLogToBackend(
|
||||
// `[DEBUG] 📦 BUFFERED chunk #${chunkIndex} (waiting for #${this.nextWriteIndex}), queue: ${this.writeQueue.size}/${this.maxBufferSize}`
|
||||
// );
|
||||
// }
|
||||
} else {
|
||||
// Buffer full, forcing processing of the earliest chunk to free up space
|
||||
await this.forceFlushOldest();
|
||||
this.writeQueue.set(chunkIndex, chunk);
|
||||
if (developmentEnv === "true") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ BUFFER_FULL, forced flush and buffered chunk #${chunkIndex}`
|
||||
);
|
||||
}
|
||||
// if (developmentEnv === "development") {
|
||||
// postLogToBackend(
|
||||
// `[DEBUG] ⚠️ BUFFER_FULL, forced flush and buffered chunk #${chunkIndex}`
|
||||
// );
|
||||
// }
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. If the chunk is expired, log a warning but ignore (already written)
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ DUPLICATE chunk #${chunkIndex} ignored (already written #${this.nextWriteIndex})`
|
||||
);
|
||||
@@ -87,7 +99,7 @@ class SequencedDiskWriter {
|
||||
await this.stream.write(firstChunk);
|
||||
this.totalWritten += firstChunk.byteLength;
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ✓ DISK_WRITE chunk #${this.nextWriteIndex} - ${firstChunk.byteLength} bytes, total: ${this.totalWritten}`
|
||||
);
|
||||
@@ -123,7 +135,7 @@ class SequencedDiskWriter {
|
||||
}
|
||||
|
||||
if (flushCount > 0) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 🔥 SEQUENTIAL_FLUSH ${flushCount} chunks, now at #${this.nextWriteIndex}, queue: ${this.writeQueue.size}`
|
||||
);
|
||||
@@ -131,6 +143,13 @@ class SequencedDiskWriter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next expected write index
|
||||
*/
|
||||
get expectedIndex(): number {
|
||||
return this.nextWriteIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force refresh the earliest chunk to release buffer space
|
||||
*/
|
||||
@@ -142,11 +161,11 @@ class SequencedDiskWriter {
|
||||
const chunk = this.writeQueue.get(oldestIndex)!;
|
||||
|
||||
// Warning: Unordered write
|
||||
if (developmentEnv === "true") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ FORCE_FLUSH out-of-order chunk #${oldestIndex} (expected #${this.nextWriteIndex})`
|
||||
);
|
||||
}
|
||||
// if (developmentEnv === "development") {
|
||||
// postLogToBackend(
|
||||
// `[DEBUG] ⚠️ FORCE_FLUSH out-of-order chunk #${oldestIndex} (expected #${this.nextWriteIndex})`
|
||||
// );
|
||||
// }
|
||||
|
||||
// Use seek to write at the correct position (fallback handling)
|
||||
const fileOffset = oldestIndex * 65536; // Assume each chunk is 64KB
|
||||
@@ -204,7 +223,7 @@ class SequencedDiskWriter {
|
||||
const fileOffset = chunkIndex * 65536;
|
||||
await this.stream.seek(fileOffset);
|
||||
await this.stream.write(chunk);
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 💾 FINAL_FLUSH chunk #${chunkIndex} at cleanup`
|
||||
);
|
||||
@@ -410,6 +429,38 @@ class FileReceiver {
|
||||
const receptionPromise = new Promise<void>((resolve, reject) => {
|
||||
const expectedChunksCount = Math.ceil((fileInfo.size - offset) / 65536); // Calculate expected chunk count
|
||||
|
||||
// 🔍 调试expectedChunksCount计算
|
||||
if (developmentEnv === "development") {
|
||||
const totalChunks = Math.ceil(fileInfo.size / 65536);
|
||||
const startChunkIndex = Math.floor(offset / 65536);
|
||||
const calculatedExpected = totalChunks - startChunkIndex;
|
||||
|
||||
postLogToBackend(`[DEBUG-CHUNKS] File: ${fileInfo.name}`);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] File size: ${fileInfo.size}, offset: ${offset}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Total chunks in file: ${totalChunks} (0-${
|
||||
totalChunks - 1
|
||||
})`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Start chunk index: ${startChunkIndex}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Expected chunks calculation: (${fileInfo.size} - ${offset}) / 65536 = ${expectedChunksCount}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Alternative calculation: ${totalChunks} - ${startChunkIndex} = ${calculatedExpected}`
|
||||
);
|
||||
|
||||
if (expectedChunksCount !== calculatedExpected) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] ⚠️ MISMATCH: ${expectedChunksCount} vs ${calculatedExpected}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.activeFileReception = {
|
||||
meta: fileInfo,
|
||||
chunks: new Array(expectedChunksCount).fill(null), // 🚀 Initialize as an empty array arranged by index
|
||||
@@ -435,7 +486,7 @@ class FileReceiver {
|
||||
this.webrtcConnection.sendData(JSON.stringify(request), this.peerId);
|
||||
this.log("log", "Sent fileRequest", { request });
|
||||
} else {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ERROR: Cannot send fileRequest - no peerId available!`
|
||||
);
|
||||
@@ -507,7 +558,7 @@ class FileReceiver {
|
||||
return true;
|
||||
});
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📁 All files in folder completed - ${folderName}, files: ${completedFileIds.length}/${folderProgress.fileIds.length}`
|
||||
);
|
||||
@@ -533,7 +584,7 @@ class FileReceiver {
|
||||
try {
|
||||
const arrayBuffer = await data.arrayBuffer();
|
||||
if (data.size !== arrayBuffer.byteLength) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ Blob size mismatch: ${data.size}→${arrayBuffer.byteLength}`
|
||||
);
|
||||
@@ -541,7 +592,7 @@ class FileReceiver {
|
||||
}
|
||||
return arrayBuffer;
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ Blob conversion failed: ${error}`);
|
||||
}
|
||||
return null;
|
||||
@@ -556,13 +607,13 @@ class FileReceiver {
|
||||
new Uint8Array(newArrayBuffer).set(uint8Array);
|
||||
return newArrayBuffer;
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ TypedArray conversion failed: ${error}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ Unknown data type: ${Object.prototype.toString.call(
|
||||
data
|
||||
@@ -584,7 +635,7 @@ class FileReceiver {
|
||||
try {
|
||||
// 1. Check minimum packet length
|
||||
if (arrayBuffer.byteLength < 4) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ Invalid embedded packet - too small: ${arrayBuffer.byteLength}`
|
||||
);
|
||||
@@ -599,7 +650,7 @@ class FileReceiver {
|
||||
// 3. Verify packet integrity
|
||||
const expectedTotalLength = 4 + metaLength;
|
||||
if (arrayBuffer.byteLength < expectedTotalLength) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ Incomplete embedded packet - expected: ${expectedTotalLength}, got: ${arrayBuffer.byteLength}`
|
||||
);
|
||||
@@ -618,7 +669,7 @@ class FileReceiver {
|
||||
|
||||
// 6. Verify chunk data size
|
||||
if (chunkData.byteLength !== chunkMeta.chunkSize) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ Chunk size mismatch - meta: ${chunkMeta.chunkSize}, actual: ${chunkData.byteLength}`
|
||||
);
|
||||
@@ -627,7 +678,7 @@ class FileReceiver {
|
||||
|
||||
return { chunkMeta, chunkData };
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ Failed to parse embedded packet: ${error}`
|
||||
);
|
||||
@@ -664,7 +715,7 @@ class FileReceiver {
|
||||
|
||||
if (arrayBuffer) {
|
||||
if (!this.activeFileReception) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ERROR: Received file chunk but no active file reception!`
|
||||
);
|
||||
@@ -679,7 +730,7 @@ class FileReceiver {
|
||||
// 🚀 Unified processing: All data is processed as embedded packets
|
||||
await this.handleEmbeddedChunkPacket(arrayBuffer);
|
||||
} else {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ERROR: Failed to convert binary data to ArrayBuffer`
|
||||
);
|
||||
@@ -773,7 +824,7 @@ class FileReceiver {
|
||||
|
||||
// Verify fileId match
|
||||
if (chunkMeta.fileId !== reception.meta.fileId) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ FileId mismatch - expected: ${reception.meta.fileId}, got: ${chunkMeta.fileId}`
|
||||
);
|
||||
@@ -781,44 +832,74 @@ class FileReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update expected chunks count (may differ from initial estimate)
|
||||
// 🔧 修复:续传时不要调整expectedChunksCount
|
||||
// chunkMeta.totalChunks是文件总chunk数,但续传时我们只接收部分chunks
|
||||
if (chunkMeta.totalChunks !== reception.expectedChunksCount) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
const startChunkIndex = Math.floor(reception.initialOffset / 65536);
|
||||
const calculatedExpected = chunkMeta.totalChunks - startChunkIndex;
|
||||
postLogToBackend(
|
||||
`[DEBUG] ⚠️ Chunk count adjustment - expected: ${reception.expectedChunksCount}, actual: ${chunkMeta.totalChunks}`
|
||||
`[DEBUG-CHUNKS] Chunk count info - fileTotal: ${chunkMeta.totalChunks}, currentExpected: ${reception.expectedChunksCount}, calculatedExpected: ${calculatedExpected}, startChunk: ${startChunkIndex}`
|
||||
);
|
||||
}
|
||||
reception.expectedChunksCount = chunkMeta.totalChunks;
|
||||
// Adjust chunks array size
|
||||
if (reception.chunks.length < chunkMeta.totalChunks) {
|
||||
const newChunks = new Array(chunkMeta.totalChunks).fill(null);
|
||||
reception.chunks.forEach((chunk, index) => {
|
||||
if (index < newChunks.length) newChunks[index] = chunk;
|
||||
});
|
||||
reception.chunks = newChunks;
|
||||
|
||||
// 🚫 不再调整expectedChunksCount,保持续传时的正确数量
|
||||
// reception.expectedChunksCount = chunkMeta.totalChunks; // 这行导致了问题!
|
||||
|
||||
if (reception.expectedChunksCount !== calculatedExpected) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] ⚠️ Expected chunks mismatch, should be ${calculatedExpected}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store chunk by index
|
||||
const chunkIndex = chunkMeta.chunkIndex;
|
||||
if (chunkIndex >= 0 && chunkIndex < reception.chunks.length) {
|
||||
reception.chunks[chunkIndex] = chunkData;
|
||||
reception.chunkSequenceMap.set(chunkIndex, true);
|
||||
// Store chunk by index - 🔧 修复:将绝对索引映射到相对索引
|
||||
const absoluteChunkIndex = chunkMeta.chunkIndex; // 发送端的绝对索引(如967-3650)
|
||||
const startChunkIndex = Math.floor(reception.initialOffset / 65536); // 续传起始索引(如967)
|
||||
const relativeChunkIndex = absoluteChunkIndex - startChunkIndex; // 在chunks数组中的相对索引(如0-2683)
|
||||
|
||||
if (developmentEnv === "development" && absoluteChunkIndex <= 970) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Index mapping - absolute:${absoluteChunkIndex}, start:${startChunkIndex}, relative:${relativeChunkIndex}, arraySize:${reception.chunks.length}`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
relativeChunkIndex >= 0 &&
|
||||
relativeChunkIndex < reception.chunks.length
|
||||
) {
|
||||
reception.chunks[relativeChunkIndex] = chunkData;
|
||||
reception.chunkSequenceMap.set(absoluteChunkIndex, true); // 序列映射仍使用绝对索引
|
||||
reception.receivedChunksCount++;
|
||||
|
||||
// Update progress
|
||||
this.updateProgress(chunkData.byteLength);
|
||||
|
||||
if (reception.sequencedWriter) {
|
||||
// 🚀 Use strict sequential write management
|
||||
await reception.sequencedWriter.writeChunk(chunkIndex, chunkData);
|
||||
// 🔍 调试chunk接收匹配 (前5个和后5个chunks)
|
||||
const lastFewChunks =
|
||||
relativeChunkIndex >= reception.expectedChunksCount - 5;
|
||||
if (
|
||||
developmentEnv === "development" &&
|
||||
(absoluteChunkIndex <= 970 || lastFewChunks)
|
||||
) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] 📦 Chunk #${absoluteChunkIndex} received - relative:${relativeChunkIndex}, size:${chunkData.byteLength}, writerExpects:${reception.sequencedWriter.expectedIndex}, isLastFew:${lastFewChunks}`
|
||||
);
|
||||
}
|
||||
|
||||
// 🚀 Use strict sequential write management - 使用绝对索引
|
||||
await reception.sequencedWriter.writeChunk(
|
||||
absoluteChunkIndex,
|
||||
chunkData
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ Invalid chunk index - ${chunkIndex}, expected 0-${
|
||||
reception.chunks.length - 1
|
||||
}`
|
||||
`[DEBUG-CHUNKS] ❌ Invalid relative chunk index - absolute:${absoluteChunkIndex}, relative:${relativeChunkIndex}, arraySize:${
|
||||
reception.chunks.length
|
||||
}, expected:0-${reception.chunks.length - 1}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -840,7 +921,8 @@ class FileReceiver {
|
||||
const currentTotalSize = reception.chunks.reduce((sum, chunk) => {
|
||||
return sum + (chunk instanceof ArrayBuffer ? chunk.byteLength : 0);
|
||||
}, 0);
|
||||
const expectedSize = reception.meta.size;
|
||||
// 🔧 修复:续传时应该比较的是剩余文件大小,不是整个文件大小
|
||||
const expectedSize = reception.meta.size - reception.initialOffset;
|
||||
|
||||
// 🚀 Unified integrity check: sequential reception mode
|
||||
let sequencedCount = 0;
|
||||
@@ -850,10 +932,55 @@ class FileReceiver {
|
||||
}
|
||||
}
|
||||
const isSequencedComplete = sequencedCount === expectedChunks;
|
||||
|
||||
const sizeComplete = currentTotalSize >= expectedSize;
|
||||
const isDataComplete = isSequencedComplete && sizeComplete;
|
||||
|
||||
// 🔍 详细调试完成检查 (减少频率,只在关键时刻输出)
|
||||
if (
|
||||
developmentEnv === "development" &&
|
||||
(isDataComplete ||
|
||||
sequencedCount % 500 === 0 ||
|
||||
sequencedCount > expectedChunks - 10)
|
||||
) {
|
||||
// 检查最后几个chunks的状态 (显示相对索引)
|
||||
const lastChunkIndex = expectedChunks - 1;
|
||||
const lastFewChunks = [];
|
||||
const startChunkIndex = Math.floor(reception.initialOffset / 65536);
|
||||
|
||||
for (let i = Math.max(0, lastChunkIndex - 3); i <= lastChunkIndex; i++) {
|
||||
const chunk = reception.chunks[i];
|
||||
const exists = chunk instanceof ArrayBuffer;
|
||||
const size = exists ? (chunk as ArrayBuffer).byteLength : 0;
|
||||
const absoluteIndex = startChunkIndex + i; // 对应的绝对索引
|
||||
lastFewChunks.push(`rel#${i}(abs#${absoluteIndex}):${exists}(${size})`);
|
||||
}
|
||||
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] Check completion - file:${reception.meta.name}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] Chunks: received:${sequencedCount}/${expectedChunks}, isSequenceComplete:${isSequencedComplete}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] Size: current:${currentTotalSize}, expected:${expectedSize}, sizeComplete:${sizeComplete}, diff:${
|
||||
expectedSize - currentTotalSize
|
||||
}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] LastChunks: ${lastFewChunks.join(", ")}`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] IsDataComplete: ${isDataComplete}, isFinalized: ${reception.isFinalized}`
|
||||
);
|
||||
|
||||
if (reception.sequencedWriter) {
|
||||
const writerStatus = reception.sequencedWriter.getBufferStatus();
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] SequencedWriter: nextIndex:${writerStatus.nextIndex}, totalWritten:${writerStatus.totalWritten}, queueSize:${writerStatus.queueSize}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent duplicate finalize
|
||||
if (reception.isFinalized) {
|
||||
return;
|
||||
@@ -862,6 +989,12 @@ class FileReceiver {
|
||||
if (isDataComplete) {
|
||||
reception.isFinalized = true;
|
||||
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-COMPLETE] ✅ Starting finalization - isDataComplete:${isDataComplete}`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.finalizeFileReceive();
|
||||
|
||||
@@ -870,7 +1003,7 @@ class FileReceiver {
|
||||
}
|
||||
this.activeFileReception = null;
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ Auto-finalize ERROR: ${error}`);
|
||||
}
|
||||
if (reception.completionNotifier) {
|
||||
@@ -958,10 +1091,14 @@ class FileReceiver {
|
||||
startChunkIndex
|
||||
);
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📢 SEQUENCED_WRITER created - startIndex: ${startChunkIndex}, offset: ${offset}`
|
||||
);
|
||||
// 🔍 调试续传接收期望
|
||||
postLogToBackend(
|
||||
`[DEBUG-RESUME] 🎯 SequencedWriter expects - startIndex:${startChunkIndex}, offset:${offset}, calculatedFrom:${offset}/65536`
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
this.fireError("Failed to create file on disk", {
|
||||
@@ -994,28 +1131,59 @@ class FileReceiver {
|
||||
|
||||
private async finalizeLargeFileReceive(): Promise<void> {
|
||||
const reception = this.activeFileReception;
|
||||
if (!reception?.writeStream || !reception.fileHandle) return;
|
||||
if (!reception?.writeStream || !reception.fileHandle) {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-FINALIZE] ❌ Cannot finalize - missing writeStream:${!!reception?.writeStream} or fileHandle:${!!reception?.fileHandle}`
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-FINALIZE] 🚀 Starting finalization for ${reception.meta.name}`
|
||||
);
|
||||
}
|
||||
|
||||
// 🚀 First close the strict sequential writing manager (flush all buffers)
|
||||
if (reception.sequencedWriter) {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG-FINALIZE] Closing SequencedWriter...`);
|
||||
}
|
||||
await reception.sequencedWriter.close();
|
||||
const status = reception.sequencedWriter.getBufferStatus();
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 💾 SEQUENCED_WRITER closed - totalWritten: ${status.totalWritten}, finalQueue: ${status.queueSize}`
|
||||
`[DEBUG-FINALIZE] 💾 SEQUENCED_WRITER closed - totalWritten: ${status.totalWritten}, finalQueue: ${status.queueSize}`
|
||||
);
|
||||
}
|
||||
reception.sequencedWriter = null;
|
||||
}
|
||||
|
||||
// Then close the file stream
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-FINALIZE] About to close writeStream for ${reception.meta.name}`
|
||||
);
|
||||
}
|
||||
await reception.writeStream.close();
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG-FINALIZE] ✅ WriteStream closed successfully`);
|
||||
}
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
postLogToBackend(`[DEBUG] ✅ LARGE_FILE finalized successfully`);
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-FINALIZE] ✅ LARGE_FILE finalized successfully - ${reception.meta.name}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG-FINALIZE] ❌ Error during finalization: ${error}`
|
||||
);
|
||||
}
|
||||
this.fireError("Error finalizing large file", { error });
|
||||
}
|
||||
}
|
||||
@@ -1040,7 +1208,7 @@ class FileReceiver {
|
||||
// Final verification
|
||||
const sizeDifference = reception.meta.size - totalChunkSize;
|
||||
if (sizeDifference !== 0) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ SIZE_MISMATCH - missing: ${sizeDifference} bytes`
|
||||
);
|
||||
@@ -1131,7 +1299,7 @@ class FileReceiver {
|
||||
this.peerId
|
||||
);
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📤 Sent folderReceiveComplete - folderName: ${folderName}, completedFiles: ${completedFileIds.length}, allStoreUpdated: ${allStoreUpdated}, success: ${success}`
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ export const trackReferrer = async () => {
|
||||
// Get URL parameters
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
let ref = urlParams.get("ref");
|
||||
if (process.env.NEXT_PUBLIC_development === "false") {
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
ref = urlParams.get("ref") || "noRef"; // Production environment, count daily active users, record as noRef if there is no ref
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { StreamingFileReader } from "./StreamingFileReader";
|
||||
import { TransferConfig } from "./TransferConfig";
|
||||
import WebRTC_Initiator from "../webrtc_Initiator";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 File transfer orchestrator
|
||||
* Integrates all components to provide unified file transfer services
|
||||
@@ -211,7 +211,7 @@ export class FileTransferOrchestrator implements MessageHandlerDelegate {
|
||||
peerState.readOffset || 0
|
||||
);
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 🚀 Starting transfer - file: ${file.name}, size: ${(
|
||||
file.size /
|
||||
@@ -301,20 +301,32 @@ export class FileTransferOrchestrator implements MessageHandlerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
const totalTime = performance.now() - transferStartTime;
|
||||
const avgSpeedMBps = totalBytesSent / 1024 / 1024 / (totalTime / 1000);
|
||||
const expectedTotalChunks = Math.ceil(file.size / 65536);
|
||||
const startOffset = peerState.readOffset || 0;
|
||||
const startChunkIndex = Math.floor(startOffset / 65536);
|
||||
const expectedChunksSent = expectedTotalChunks - startChunkIndex;
|
||||
|
||||
postLogToBackend(
|
||||
`[DEBUG] ✅ Transfer complete - file: ${file.name}, time: ${(
|
||||
`[DEBUG-CHUNKS] ✅ Transfer complete - file: ${file.name}, time: ${(
|
||||
totalTime / 1000
|
||||
).toFixed(1)}s, speed: ${avgSpeedMBps.toFixed(
|
||||
1
|
||||
)}MB/s, chunks: ${networkChunkIndex}`
|
||||
).toFixed(1)}s, speed: ${avgSpeedMBps.toFixed(1)}MB/s`
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] Chunks sent: ${networkChunkIndex}, expected: ${expectedChunksSent}, startChunk: ${startChunkIndex}, totalFileChunks: ${expectedTotalChunks}`
|
||||
);
|
||||
|
||||
if (networkChunkIndex !== expectedChunksSent) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] ⚠️ CHUNK MISMATCH: sent ${networkChunkIndex} but expected ${expectedChunksSent}`
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
const errorMessage = `Streaming send error: ${error.message}`;
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ Transfer error: ${errorMessage}`);
|
||||
}
|
||||
this.fireError(errorMessage, {
|
||||
@@ -428,7 +440,7 @@ export class FileTransferOrchestrator implements MessageHandlerDelegate {
|
||||
public handlePeerReconnection(peerId: string): void {
|
||||
// Clear all transfer states for this peer
|
||||
this.stateManager.clearPeerState(peerId);
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
this.log(
|
||||
"log",
|
||||
`Successfully reset transfer state for reconnected peer ${peerId}`
|
||||
@@ -443,7 +455,7 @@ export class FileTransferOrchestrator implements MessageHandlerDelegate {
|
||||
this.networkTransmitter.cleanup();
|
||||
this.progressTracker.cleanup();
|
||||
this.messageHandler.cleanup();
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
this.log("log", "FileTransferOrchestrator cleaned up");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from "@/types/webrtc";
|
||||
import { StateManager } from "./StateManager";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 Message handling interface - Communicate with main orchestrator
|
||||
*/
|
||||
@@ -120,7 +120,7 @@ export class MessageHandler {
|
||||
message: FolderReceiveComplete,
|
||||
peerId: string
|
||||
): void {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📥 Folder complete - folderName: ${message.folderName}, files: ${message.completedFileIds.length}`
|
||||
);
|
||||
@@ -172,7 +172,7 @@ export class MessageHandler {
|
||||
* 🧹 Clean up resources
|
||||
*/
|
||||
public cleanup(): void {
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend("[DEBUG] 🧹 MessageHandler cleaned up");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { EmbeddedChunkMeta } from "@/types/webrtc";
|
||||
import { StateManager } from "./StateManager";
|
||||
import WebRTC_Initiator from "../webrtc_Initiator";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 Network transmitter - Simplified version
|
||||
* Uses WebRTC native bufferedAmountLowThreshold for backpressure control
|
||||
@@ -34,7 +34,7 @@ export class NetworkTransmitter {
|
||||
// Key node logs (development environment only)
|
||||
|
||||
if (
|
||||
developmentEnv === "true" &&
|
||||
developmentEnv === "development" &&
|
||||
(metadata.chunkIndex % 100 === 0 || metadata.isLastChunk)
|
||||
) {
|
||||
postLogToBackend(
|
||||
@@ -48,7 +48,7 @@ export class NetworkTransmitter {
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] ❌ CHUNK #${metadata.chunkIndex} send failed: ${error}`
|
||||
);
|
||||
@@ -106,7 +106,7 @@ export class NetworkTransmitter {
|
||||
if (!sendResult) {
|
||||
const errorMessage = `sendData failed`;
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ ${errorMessage}`);
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
@@ -148,7 +148,7 @@ export class NetworkTransmitter {
|
||||
});
|
||||
|
||||
// Only output backpressure logs in development environment
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
const waitTime = performance.now() - startTime;
|
||||
postLogToBackend(
|
||||
`[DEBUG] 🚀 BACKPRESSURE - wait: ${waitTime.toFixed(
|
||||
@@ -182,7 +182,7 @@ export class NetworkTransmitter {
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = `sendWithBackpressure failed: ${error}`;
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ ${errorMessage}`);
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
@@ -239,7 +239,7 @@ export class NetworkTransmitter {
|
||||
* 🧹 Clean up resources
|
||||
*/
|
||||
public cleanup(): void {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend("[DEBUG] 🧹 NetworkTransmitter cleaned up");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SpeedCalculator } from "@/lib/speedCalculator";
|
||||
import { StateManager } from "./StateManager";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 Progress callback type definition
|
||||
*/
|
||||
@@ -225,7 +225,7 @@ export class ProgressTracker {
|
||||
*/
|
||||
cleanup(): void {
|
||||
// SpeedCalculator internally automatically cleans up expired data
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend("[DEBUG] 🧹 ProgressTracker cleaned up");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CustomFile } from "@/types/webrtc";
|
||||
import { TransferConfig } from "./TransferConfig";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!;
|
||||
const developmentEnv = process.env.NODE_ENV;
|
||||
/**
|
||||
* 🚀 Network chunk interface
|
||||
*/
|
||||
@@ -46,9 +46,11 @@ export class StreamingFileReader {
|
||||
this.file = file;
|
||||
this.totalFileSize = file.size;
|
||||
this.totalFileOffset = startOffset;
|
||||
// 🔧 修复:续传时currentBatchStartOffset应该从startOffset开始
|
||||
this.currentBatchStartOffset = startOffset;
|
||||
this.fileReader = new FileReader();
|
||||
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 📖 StreamingFileReader created - file: ${file.name}, size: ${(
|
||||
this.totalFileSize /
|
||||
@@ -56,6 +58,13 @@ export class StreamingFileReader {
|
||||
1024
|
||||
).toFixed(1)}MB`
|
||||
);
|
||||
// 🔍 调试续传初始化
|
||||
const expectedGlobalChunk = Math.floor(
|
||||
startOffset / this.NETWORK_CHUNK_SIZE
|
||||
);
|
||||
postLogToBackend(
|
||||
`[DEBUG-RESUME] 🏗️ StreamingFileReader created - totalFileOffset:${this.totalFileOffset}, currentBatchStartOffset:${this.currentBatchStartOffset}, expectedGlobalChunk:${expectedGlobalChunk}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +98,15 @@ export class StreamingFileReader {
|
||||
|
||||
// Delete frequent chunk progress logs
|
||||
|
||||
// 🔍 调试chunk发送 (前5个和最后5个chunks)
|
||||
const totalChunks = this.calculateTotalNetworkChunks();
|
||||
const isLastFew = globalChunkIndex >= (totalChunks - 5);
|
||||
if (developmentEnv === "development" && (globalChunkIndex <= 5 || isLastFew || isLast)) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-CHUNKS] 📤 Send chunk #${globalChunkIndex}/${totalChunks} - size:${networkChunk.byteLength}, isLast:${isLast}, fileOffset:${this.totalFileOffset - networkChunk.byteLength}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
chunk: networkChunk,
|
||||
chunkIndex: globalChunkIndex,
|
||||
@@ -160,11 +178,24 @@ export class StreamingFileReader {
|
||||
this.currentBatch = await this.readFileSlice(fileSlice);
|
||||
const readTime = performance.now() - readStartTime;
|
||||
|
||||
this.currentBatchStartOffset = this.totalFileOffset;
|
||||
this.currentChunkIndexInBatch = 0;
|
||||
const batchStartOffset = this.totalFileOffset;
|
||||
this.currentBatchStartOffset = batchStartOffset;
|
||||
|
||||
// 🔧 修复:如果不是从batch边界开始,说明是续传情况,需要计算正确的batch内索引
|
||||
if (batchStartOffset % this.BATCH_SIZE !== 0) {
|
||||
// 续传情况:不是从batch边界开始
|
||||
const globalChunkIndex = Math.floor(
|
||||
batchStartOffset / this.NETWORK_CHUNK_SIZE
|
||||
);
|
||||
this.currentChunkIndexInBatch =
|
||||
globalChunkIndex % this.CHUNKS_PER_BATCH;
|
||||
} else {
|
||||
// 正常情况:从batch边界开始
|
||||
this.currentChunkIndexInBatch = 0;
|
||||
}
|
||||
|
||||
// Only output batch reading logs in development environment
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
const totalTime = performance.now() - startTime;
|
||||
const speedMBps = batchSize / 1024 / 1024 / (totalTime / 1000);
|
||||
postLogToBackend(
|
||||
@@ -174,9 +205,15 @@ export class StreamingFileReader {
|
||||
1
|
||||
)}MB/s`
|
||||
);
|
||||
// 🔍 调试batch内索引设置
|
||||
postLogToBackend(
|
||||
`[DEBUG-RESUME] 📖 BATCH loaded - batchStartOffset:${batchStartOffset}, currentChunkIndexInBatch:${
|
||||
this.currentChunkIndexInBatch
|
||||
}, isResume:${batchStartOffset % this.BATCH_SIZE !== 0}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`[DEBUG] ❌ BATCH_READ failed: ${error}`);
|
||||
}
|
||||
throw new Error(`Failed to load file batch: ${error}`);
|
||||
@@ -247,7 +284,19 @@ export class StreamingFileReader {
|
||||
this.currentBatchStartOffset / this.BATCH_SIZE
|
||||
);
|
||||
const chunksInPreviousBatches = batchesBefore * this.CHUNKS_PER_BATCH;
|
||||
return chunksInPreviousBatches + this.currentChunkIndexInBatch;
|
||||
const result = chunksInPreviousBatches + this.currentChunkIndexInBatch;
|
||||
|
||||
// 🔍 调试chunk索引计算
|
||||
if (
|
||||
developmentEnv === "development" &&
|
||||
this.currentChunkIndexInBatch <= 5
|
||||
) {
|
||||
postLogToBackend(
|
||||
`[DEBUG-RESUME] 🧮 calculateGlobalChunkIndex - batchStartOffset:${this.currentBatchStartOffset}, batchesBefore:${batchesBefore}, chunksInPrev:${chunksInPreviousBatches}, chunkInBatch:${this.currentChunkIndexInBatch}, result:${result}`
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,10 +373,14 @@ export class StreamingFileReader {
|
||||
this.isFinished = false;
|
||||
this.isReading = false;
|
||||
this.currentBatch = null;
|
||||
this.currentBatchStartOffset = 0;
|
||||
this.currentChunkIndexInBatch = 0;
|
||||
if (developmentEnv === "true") {
|
||||
postLogToBackend(`[DEBUG] 🔄 StreamingFileReader reset`);
|
||||
// 🔧 修复:reset时也要正确设置currentBatchStartOffset
|
||||
this.currentBatchStartOffset = startOffset;
|
||||
this.currentChunkIndexInBatch = 0; // 重置为0,loadNextBatch会重新计算
|
||||
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`[DEBUG] 🔄 StreamingFileReader reset - startOffset:${startOffset}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Initiator flow: Join room; receive 'ready' event (this event is triggered by the socket server after a new recipient enters) -> createPeerConnection + createDataChannel -> createAndSendOffer
|
||||
import BaseWebRTC, { WebRTCConfig } from "./webrtc_base";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!; // Development environment
|
||||
const developmentEnv = process.env.NODE_ENV; // Development environment
|
||||
|
||||
export default class WebRTC_Initiator extends BaseWebRTC {
|
||||
constructor(config: WebRTCConfig) {
|
||||
@@ -16,7 +16,7 @@ export default class WebRTC_Initiator extends BaseWebRTC {
|
||||
});
|
||||
// Add listener for recipient's response
|
||||
this.socket.on("recipient-ready", ({ peerId }) => {
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(
|
||||
`[Initiator] Received recipient-ready from: ${peerId}`
|
||||
);
|
||||
@@ -32,7 +32,7 @@ export default class WebRTC_Initiator extends BaseWebRTC {
|
||||
private async handleReady({ peerId }: { peerId: string }): Promise<void> {
|
||||
// Recipient peerId
|
||||
// this.log('log',`Received ready signal from peer ${peerId}`);
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(`Received ready signal from peer ${peerId}`);
|
||||
await this.createPeerConnection(peerId);
|
||||
await this.createDataChannel(peerId);
|
||||
@@ -48,7 +48,7 @@ export default class WebRTC_Initiator extends BaseWebRTC {
|
||||
from: string;
|
||||
}): Promise<void> {
|
||||
// this.log('log',`Handling answer from peer ${from}`);
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(`Handling answer from peer ${from}`);
|
||||
const peerConnection = this.peerConnections.get(from);
|
||||
if (!peerConnection) {
|
||||
@@ -96,7 +96,7 @@ export default class WebRTC_Initiator extends BaseWebRTC {
|
||||
// If it is the initiator, create and send an offer to the signaling server to negotiate a connection with the recipient.
|
||||
private async createAndSendOffer(peerId: string): Promise<void> {
|
||||
// this.log('log', `Creating and sending offer to ${peerId}`);
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(`createAndSendOffer for peerId: ${peerId}`);
|
||||
const peerConnection = this.peerConnections.get(peerId);
|
||||
if (!peerConnection) {
|
||||
|
||||
+11
-11
@@ -2,7 +2,7 @@
|
||||
import io, { Socket, ManagerOptions, SocketOptions } from "socket.io-client";
|
||||
import { WakeLockManager } from "./wakeLockManager";
|
||||
import { postLogToBackend } from "@/app/config/api";
|
||||
const developmentEnv = process.env.NEXT_PUBLIC_development!; // Development environment
|
||||
const developmentEnv = process.env.NODE_ENV; // Development environment
|
||||
|
||||
export class WebRTCError extends Error {
|
||||
constructor(message: string, public context?: Record<string, any>) {
|
||||
@@ -131,7 +131,7 @@ export default class BaseWebRTC {
|
||||
this.socket.on("disconnect", () => {
|
||||
this.isInRoom = false;
|
||||
this.isSocketDisconnected = true;
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(
|
||||
`${this.peerId} disconnect on socket,isInitiator:${this.isInitiator},isInRoom:${this.isInRoom}`
|
||||
);
|
||||
@@ -153,7 +153,7 @@ export default class BaseWebRTC {
|
||||
if (this.isSocketDisconnected && this.isPeerDisconnected && this.roomId) {
|
||||
// Start reconnection only after both socket and P2P connections are disconnected
|
||||
this.reconnectionInProgress = true;
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(
|
||||
`Starting reconnection, socket and peer both disconnected. isInitiator:${this.isInitiator}`
|
||||
);
|
||||
@@ -314,7 +314,7 @@ export default class BaseWebRTC {
|
||||
disconnected: async () => {
|
||||
await this.cleanupExistingConnection(peerId);
|
||||
this.isPeerDisconnected = true;
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(`p2p disconnected, isInitiator:${this.isInitiator}`);
|
||||
// Attempt to reconnect
|
||||
this.attemptReconnection();
|
||||
@@ -402,7 +402,7 @@ export default class BaseWebRTC {
|
||||
};
|
||||
|
||||
dataChannel.onclose = () => {
|
||||
if (developmentEnv === "true") {
|
||||
if (developmentEnv === "development") {
|
||||
postLogToBackend(`DataChannel closed for peer: ${peerId}`);
|
||||
}
|
||||
this.log("log", `Data channel with ${peerId} closed.`);
|
||||
@@ -440,7 +440,7 @@ export default class BaseWebRTC {
|
||||
roomId: this.roomId,
|
||||
});
|
||||
}
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(
|
||||
`peerId:${this.socket.id} Successfully joined room: ${response.roomId},isInitiator:${this.isInitiator},isInRoom:${this.isInRoom}`
|
||||
);
|
||||
@@ -448,7 +448,7 @@ export default class BaseWebRTC {
|
||||
} else {
|
||||
this.isInRoom = false;
|
||||
this.roomId = null;
|
||||
if (developmentEnv === "true")
|
||||
if (developmentEnv === "development")
|
||||
postLogToBackend(`Failed to join room,message:${response.message}`);
|
||||
this.fireError("Failed to join room", { message: response.message });
|
||||
reject(new Error(response.message));
|
||||
@@ -499,10 +499,10 @@ export default class BaseWebRTC {
|
||||
? data.byteLength
|
||||
: 0;
|
||||
|
||||
if (developmentEnv === "true")
|
||||
postLogToBackend(
|
||||
`sendToPeer - type: ${dataType}, size: ${dataSize}, bufferedAmount: ${dataChannel.bufferedAmount}`
|
||||
);
|
||||
// if (developmentEnv === "development")
|
||||
// postLogToBackend(
|
||||
// `sendToPeer - type: ${dataType}, size: ${dataSize}, bufferedAmount: ${dataChannel.bufferedAmount}`
|
||||
// );
|
||||
|
||||
dataChannel.send(data);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user