Files
webrtc-real-time-ip-phone/frontend-web-vanilla/src/call/Caller.ts
2025-11-28 13:47:17 -05:00

68 lines
2.2 KiB
TypeScript

import type { ISignalingClient } from '../interfaces/ISignalingClient';
import type { IPeerConnectionOperations } from '../interfaces/IPeerConnectionOperations';
import type { ILogger } from '@techniker-me/logger';
import { LoggerFactory } from '@techniker-me/logger';
/**
* Caller class - responsible for initiating WebRTC calls
* Follows Single Responsibility Principle - only handles offer creation flow
* Follows Dependency Inversion Principle - depends on abstractions (interfaces)
*/
export class Caller {
private readonly _logger: ILogger = LoggerFactory.getLogger('Caller');
private readonly _signalingClient: ISignalingClient;
private readonly _peerConnection: IPeerConnectionOperations;
constructor(
signalingClient: ISignalingClient,
peerConnection: IPeerConnectionOperations
) {
this._signalingClient = signalingClient;
this._peerConnection = peerConnection;
}
/**
* Create and send an offer following the sequence diagram:
* 1. Create Offer
* 2. Set local description to offer
* 3. Send Offer to signaling server
*/
public async createAndSendOffer(): Promise<void> {
try {
this._logger.info('Creating offer...');
// Step 1: Create Offer
const offer = await this._peerConnection.createOffer();
// Step 2: Set local description to offer
await this._peerConnection.setLocalDescription(offer);
this._logger.info('Local description set to offer');
// Step 3: Send Offer to signaling server
await this._signalingClient.sendOffer(offer);
this._logger.info('Offer sent to signaling server');
} catch (error) {
this._logger.error('Failed to create and send offer', error);
throw error;
}
}
/**
* Handle receiving an answer from the callee
* Sets the answer as remote description
*/
public async handleAnswer(answer: RTCSessionDescriptionInit): Promise<void> {
try {
this._logger.info('Handling answer from callee...');
// Set Answer as remote description
await this._peerConnection.setRemoteDescription(answer);
this._logger.info('Answer set as remote description');
} catch (error) {
this._logger.error('Failed to handle answer', error);
throw error;
}
}
}