feat(wsService, WebRTCManager): enhance call handling with media type support and negotiation improvements
- Added optional media_type to WSCallIncomingMessage for better call type differentiation. - Updated call_type assignment in WebSocketService to prioritize media_type if available. - Removed initialOfferCreated flag in WebRTCManager to simplify negotiation logic. - Improved negotiation handling by releasing the negotiation lock after offer creation, ensuring smoother call setup.
This commit is contained in:
@@ -38,7 +38,6 @@ class WebRTCManager {
|
|||||||
private isInitiator = false;
|
private isInitiator = false;
|
||||||
private callType: CallType = 'voice';
|
private callType: CallType = 'voice';
|
||||||
private isNegotiating = false;
|
private isNegotiating = false;
|
||||||
private initialOfferCreated = false; // Flag to prevent duplicate offer creation
|
|
||||||
|
|
||||||
async initialize(iceServers: ICEServer[] = []): Promise<void> {
|
async initialize(iceServers: ICEServer[] = []): Promise<void> {
|
||||||
if (this.peerConnection) {
|
if (this.peerConnection) {
|
||||||
@@ -103,19 +102,17 @@ class WebRTCManager {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
pc.onnegotiationneeded = async () => {
|
pc.onnegotiationneeded = async () => {
|
||||||
console.log('[WebRTC] Negotiation needed, signalingState:', pc.signalingState, 'isNegotiating:', this.isNegotiating);
|
console.log('[WebRTC] Negotiation needed, signalingState:', pc.signalingState, 'isNegotiating:', this.isNegotiating);
|
||||||
|
|
||||||
// Check if peer connection is still valid
|
// Check if peer connection is still valid
|
||||||
if (!this.peerConnection || this.peerConnection !== pc) {
|
if (!this.peerConnection || this.peerConnection !== pc) {
|
||||||
console.log('[WebRTC] PeerConnection changed or disposed, skipping negotiation');
|
console.log('[WebRTC] PeerConnection changed or disposed, skipping negotiation');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only start negotiation if:
|
// Only start negotiation if:
|
||||||
// 1. We're in stable state
|
// 1. We're in stable state
|
||||||
// 2. Not already negotiating
|
// 2. Not already negotiating
|
||||||
// 3. We are the initiator
|
if (pc.signalingState === 'stable' && !this.isNegotiating) {
|
||||||
// 4. Initial offer has NOT been created yet (prevent duplicate during startCall)
|
|
||||||
if (pc.signalingState === 'stable' && !this.isNegotiating && this.isInitiator && !this.initialOfferCreated) {
|
|
||||||
try {
|
try {
|
||||||
this.isNegotiating = true;
|
this.isNegotiating = true;
|
||||||
const offer = await this.createOffer();
|
const offer = await this.createOffer();
|
||||||
@@ -132,7 +129,7 @@ class WebRTCManager {
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[WebRTC] Skipping negotiation: state=', pc.signalingState, 'isNegotiating=', this.isNegotiating, 'isInitiator=', this.isInitiator, 'initialOfferCreated=', this.initialOfferCreated);
|
console.log('[WebRTC] Skipping negotiation: state=', pc.signalingState, 'isNegotiating=', this.isNegotiating);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -199,7 +196,7 @@ class WebRTCManager {
|
|||||||
|
|
||||||
this.isInitiator = isInitiator;
|
this.isInitiator = isInitiator;
|
||||||
this.callType = callType;
|
this.callType = callType;
|
||||||
this.initialOfferCreated = true; // Set flag BEFORE creating connection to prevent onnegotiationneeded
|
this.isNegotiating = true; // Prevent onnegotiationneeded from firing during setup
|
||||||
this.peerConnection = this.createPeerConnection();
|
this.peerConnection = this.createPeerConnection();
|
||||||
|
|
||||||
// Setup transceivers FIRST - this ensures consistent m-line order
|
// Setup transceivers FIRST - this ensures consistent m-line order
|
||||||
@@ -207,7 +204,7 @@ class WebRTCManager {
|
|||||||
|
|
||||||
// Now add local tracks to transceivers
|
// Now add local tracks to transceivers
|
||||||
const transceivers = this.peerConnection.getTransceivers();
|
const transceivers = this.peerConnection.getTransceivers();
|
||||||
|
|
||||||
// Add audio track to audio transceiver
|
// Add audio track to audio transceiver
|
||||||
const audioTrack = this.localStream.getAudioTracks()[0];
|
const audioTrack = this.localStream.getAudioTracks()[0];
|
||||||
const audioTransceiver = transceivers.find(t => t.receiver.track?.kind === 'audio');
|
const audioTransceiver = transceivers.find(t => t.receiver.track?.kind === 'audio');
|
||||||
@@ -227,8 +224,14 @@ class WebRTCManager {
|
|||||||
if (isInitiator) {
|
if (isInitiator) {
|
||||||
// For initiator, create offer directly here
|
// For initiator, create offer directly here
|
||||||
const offer = await this.createOffer();
|
const offer = await this.createOffer();
|
||||||
|
// Release negotiation lock after a delay to allow state to settle
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isNegotiating = false;
|
||||||
|
}, 500);
|
||||||
return offer;
|
return offer;
|
||||||
}
|
}
|
||||||
|
// For non-initiator, release lock immediately since no offer is created
|
||||||
|
this.isNegotiating = false;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +550,6 @@ class WebRTCManager {
|
|||||||
this.eventHandlers.clear();
|
this.eventHandlers.clear();
|
||||||
this.pendingCandidates = [];
|
this.pendingCandidates = [];
|
||||||
this.isNegotiating = false;
|
this.isNegotiating = false;
|
||||||
this.initialOfferCreated = false;
|
|
||||||
|
|
||||||
if (this.localStream) {
|
if (this.localStream) {
|
||||||
this.localStream.getTracks().forEach((track) => track.stop());
|
this.localStream.getTracks().forEach((track) => track.stop());
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export interface WSCallIncomingMessage {
|
|||||||
conversation_id: string;
|
conversation_id: string;
|
||||||
caller_id: string;
|
caller_id: string;
|
||||||
call_type: string;
|
call_type: string;
|
||||||
|
media_type?: string;
|
||||||
created_at: number;
|
created_at: number;
|
||||||
lifetime?: number;
|
lifetime?: number;
|
||||||
ice_servers?: ICEServerConfig[];
|
ice_servers?: ICEServerConfig[];
|
||||||
@@ -621,7 +622,7 @@ class WebSocketService {
|
|||||||
call_id: payload.call_id,
|
call_id: payload.call_id,
|
||||||
conversation_id: payload.conversation_id,
|
conversation_id: payload.conversation_id,
|
||||||
caller_id: payload.caller_id,
|
caller_id: payload.caller_id,
|
||||||
call_type: payload.call_type,
|
call_type: payload.media_type || payload.call_type,
|
||||||
created_at: payload.created_at,
|
created_at: payload.created_at,
|
||||||
lifetime: payload.lifetime,
|
lifetime: payload.lifetime,
|
||||||
ice_servers: payload.ice_servers,
|
ice_servers: payload.ice_servers,
|
||||||
|
|||||||
Reference in New Issue
Block a user