mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-25 03:10:08 +08:00
* refactor: change qrcode landrop to lantransfer * chore: update docs and tests * fix: pr review * fix: pr review * chore: remove qrcode dependency * fix: pr review * fix: format * fix: test
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import type { Socket } from 'node:net'
|
|
|
|
/**
|
|
* Binary protocol constants (v1)
|
|
*/
|
|
export const BINARY_TYPE_FILE_CHUNK = 0x01
|
|
|
|
/**
|
|
* Send file chunk as binary frame (protocol v1 - streaming mode)
|
|
*
|
|
* Frame format:
|
|
* ```
|
|
* ┌──────────┬──────────┬──────────┬───────────────┬──────────────┬────────────┬───────────┐
|
|
* │ Magic │ TotalLen │ Type │ TransferId Len│ TransferId │ ChunkIdx │ Data │
|
|
* │ 0x43 0x53│ (4B BE) │ 0x01 │ (2B BE) │ (variable) │ (4B BE) │ (raw) │
|
|
* └──────────┴──────────┴──────────┴───────────────┴──────────────┴────────────┴───────────┘
|
|
* ```
|
|
*
|
|
* @param socket - TCP socket to write to
|
|
* @param transferId - UUID of the transfer
|
|
* @param chunkIndex - Index of the chunk (0-based)
|
|
* @param data - Raw chunk data buffer
|
|
* @returns true if data was buffered, false if backpressure should be applied
|
|
*/
|
|
export function sendBinaryChunk(socket: Socket, transferId: string, chunkIndex: number, data: Buffer): boolean {
|
|
if (!socket || socket.destroyed || !socket.writable) {
|
|
throw new Error('Socket is not writable')
|
|
}
|
|
|
|
const tidBuffer = Buffer.from(transferId, 'utf8')
|
|
const tidLen = tidBuffer.length
|
|
|
|
// totalLen = type(1) + tidLen(2) + tid(n) + idx(4) + data(m)
|
|
const totalLen = 1 + 2 + tidLen + 4 + data.length
|
|
|
|
const header = Buffer.allocUnsafe(2 + 4 + 1 + 2 + tidLen + 4)
|
|
let offset = 0
|
|
|
|
// Magic (2 bytes): "CS"
|
|
header[offset++] = 0x43
|
|
header[offset++] = 0x53
|
|
|
|
// TotalLen (4 bytes, Big-Endian)
|
|
header.writeUInt32BE(totalLen, offset)
|
|
offset += 4
|
|
|
|
// Type (1 byte)
|
|
header[offset++] = BINARY_TYPE_FILE_CHUNK
|
|
|
|
// TransferId length (2 bytes, Big-Endian)
|
|
header.writeUInt16BE(tidLen, offset)
|
|
offset += 2
|
|
|
|
// TransferId (variable)
|
|
tidBuffer.copy(header, offset)
|
|
offset += tidLen
|
|
|
|
// ChunkIndex (4 bytes, Big-Endian)
|
|
header.writeUInt32BE(chunkIndex, offset)
|
|
|
|
socket.cork()
|
|
const wroteHeader = socket.write(header)
|
|
const wroteData = socket.write(data)
|
|
socket.uncork()
|
|
|
|
return wroteHeader && wroteData
|
|
}
|