npaw-plugin-nwf
Version:
NPAW's Plugin
261 lines (260 loc) • 9.1 kB
TypeScript
import { VideoSegment } from '../Storage/VideoSegment';
import Emitter from '../Utils/Emitter';
import P2PLoader from './../Loaders/P2PLoader';
import * as peer from 'simple-peer';
/**
* @class
* @description Peer class, abstraction of all the logic that contains one unique peer used by the p2p client
* @extends Emitter
* @exports Peer
*/
export default class Peer extends Emitter {
id: string;
private _peer;
/**
* V2 protocol: remote peer's cache indexed by segmentId. Replaces the flat
* `string[]` map of v1. Insertion order matters for LRU-style eviction when
* the peer reports its declared storageSize. Parity with iOS/Android
* `remoteSegments`.
*/
private _remoteSegments;
private _activeDownloads;
private _lastResponses;
private _lastSent;
private _decoder;
private _identifierShort;
private _downloaded;
private _totalDownloaded;
private _totalDownloadedBytes;
private _totalDownloadTime;
consecutiveHaveSegment: number;
timeouts: number;
downloadingProcessActive: boolean;
private _version;
private _totalSendBytes;
private _totalSendTime;
private _totalSendSegments;
private _loader;
private _lastLatencyP2P;
private _lastLatencySegment;
private _lastBandwith;
/** EMA of per-peer transfer speed in bytes/sec. -1 means no data yet. Parity with iOS/Android. */
private _avgBytesPerSecond;
private _transferSamples;
private _answer;
private _ip;
private _segmendDataMessages;
private _lastSegmendDataMessagesTime;
private _destroyed;
foreSegmentsInfo: boolean;
isAhead: boolean;
isBehind: boolean;
timeGap: number;
private _operationId;
getIceAnswer(): any;
totalErrors: number;
private _cancel;
private testLatencyDone;
private testBandwidthDone;
private testLatencyResult;
private testBandwidthResult;
getTotalSendBytes(): number;
getTotalSendTime(): number;
getTotalSendSegments(): number;
getDownloadedBytes(): number;
getDownloadedChunks(): number;
getDownloadBandwidth(): number;
getLastLatencyP2P(): number;
getLastLatencySegment(): number;
getLastBandwith(): number;
getIp(): any;
getLastResponses(): responseStorageObject[];
/**
* Constructs peer.
* @param {peer} peer Peer data.
*/
constructor(loader: P2PLoader, peer: peer, answer: any);
getVersion(): number;
/**
* Returns if the peer is currently managing an active download.
* @returns {boolean} If the peer is on an active download.
* @public
*/
isDownloading(): boolean;
getSegmentDataMessages(): number;
getLastSegmentDataMessagesTime(): number;
addTimeout(): void;
decayTimeout(): void;
/**
* Returns whether the remote peer currently has the segment usable for serving.
* Matches iOS/Android v2 filter: READY always, ACQUIRING only while its lease is
* still valid. Anything else (FAILED, EVICTED, UNKNOWN) is considered absent.
*/
hasSegment(segmentId: string): boolean;
/**
* Returns the raw remote state for a segment, or undefined if absent.
* Useful for leader-election decisions (PRIMARY/BACKUP/NONE).
*/
remoteSegmentState(segmentId: string): RemoteSegmentState | undefined;
/**
* Applies an incoming SEGMENT_STATE message to the peer's remote cache mirror.
* `leaseMs` is relative (ms-from-now); we store the absolute expiry timestamp.
*/
updateSegmentState(segmentId: string, state: string, role: string, leaseMs?: number): void;
/**
* Clears all tracked remote segments. Called on peer disconnect and on
* swarm switch (parity with iOS `resetRemoteKeys`).
*/
resetRemoteKeys(): void;
/**
* Records a completed P2P transfer from this peer and updates the EMA of
* per-peer bandwidth. Parity with iOS `Peer.recordTransferSpeed`.
*/
recordTransferSpeed(bytes: number, elapsedMs: number): void;
/** True once we have enough samples to trust `getAvgBytesPerSecond`. */
hasSpeedData(): boolean;
getAvgBytesPerSecond(): number;
/**
* Sends a SEGMENT_STATE announcement to this peer. Used by the local CDN
* capture path to pre-announce an ACQUIRING segment (early announcement),
* and later to confirm READY / FAILED. Parity with Android `sendSegmentState`.
*/
sendSegmentState(segmentId: string, state: string, role: string, leaseMs?: number): Promise<void>;
/**
* Destroys this peer, uses the same code executed on close peer event.
* @public
*/
destroy(): void;
/**
* Callback for peer connect event, saves the address and notifies it.
* @private
*/
private _onConnect;
/**
* Callback for peer error event, checks if we need to close it.
* @private
*/
private _onError;
/**
* Callback for peer close event, fails the requests.
* @private
*/
private _onClose;
/**
* Reset values of the download to allow more requests.
* @private
*/
private _endDownload;
/**
* Callback method for peers response.
* @param {ArrayBuffer} data Message received from the peer.
* @private
*/
private _onData;
/**
* Requests a video segment with its id.
* @param {string} id Id of the segment to request.
* @public
*/
request(id: string, firstByteTimeoutMs?: number): void;
/**
* @public
*/
ping(id: string): void;
/**
* @public
*/
pong(id: string, time: number): void;
/**
* Cancel a video segment request with its id.
* @param {string} id Id of the segment to cancel.
* @public
*/
private _cancelRequest;
/**
* Sends the segment map object.
* @param {map} map Segment map object.
* @public
*/
sendMap(map: map): Promise<void>;
/**
* Given a segment and its id, sends it to the peer split in messages if needed.
* @param {string} id Id of the segment.
* @param {VideoSegment} segment The segment to send itself.
* @param {number} identifier Identifier of the message.
* @public
*/
sendSegment(id: string, segment: VideoSegment, operationId: number): Promise<void>;
private getByteArrayFromIdentifier;
private getIdentifierFromByteArray;
/**
* V2 upload path: same wire format as `sendSegment` but accepts a raw
* byte array instead of a VideoSegment. Used to serve READY payloads that
* live in the DiskSegmentStore rather than the legacy SegmentStorage.
*/
sendRawSegment(id: string, bytes: Uint8Array, operationId: number): Promise<void>;
/**
* Sends a message of no segment available to the peer.
* @param {string} id Id of the segment.
* @public
*/
sendNoSegment(id: string, operationId: number): void;
/**
* Sends the segment map object.
* @param {map} map Segment map object.
* @public
*/
sendNewSegmentAvailable(segmentId: string, size: number, storageSize: number, createdAt: number): Promise<void>;
/**
* Sends the given object to the peer.
* @param {peerMessage} msg Message to send.
* @param {number} id ID number to send in first bytes of the message.
* @private
*/
private _send;
/**
* Returns the IDs of segments that this remote peer currently has available to serve.
* Filters the full remote-state map through the same rule as `hasSegment` so legacy
* callers that do `getSegmentMap().indexOf(id) >= 0` keep working against v2 state.
* @public
*/
getSegmentMap(): map;
/**
* Total count of tracked remote segments (includes states not visible via
* `getSegmentMap()`, used for storage-size trimming parity with iOS/Android).
*/
getRemoteSegmentsSize(): number;
/**
* Starts the peer timeout for the download.
* @param {string} id Id of the peer.
* @private
*/
private _startTimeout;
/**
* Returns the timestamp of the oldest request stored in the lastResponses object, or 0 if is empty.
* @returns {number} Timestamp of the oldest stored request.
* @public
*/
getOldestRequestTS(): number;
/**
* Returns the bytes downloaded/uploaded from the Peer the last -defined- seconds.
* Definition in constants: StatsSettings.totalDataInterval
* @returns {number} Bytes downloaded.
* @private
*/
private static _getLastSecondsTraffic;
/**
* Returns the bytes downloaded from the peers the last -defined- seconds. 60 By default.
* Definition in constants: StatsSettings.totalDataInterval
* @returns {number} Bytes downloaded.
* @public
*/
getLastDownloadsTraffic(): number;
/**
* Returns the bytes uploaded from the peers the last -defined- seconds. 60 By default.
* Definition in constants: StatsSettings.totalDataInterval
* @returns {number} Bytes downloaded.
* @public
*/
getLastUploadsTraffic(): number;
}