private ResonanceActionResult <WebRTCOfferResponse> OnWebRTCOfferRequest(WebRTCOfferRequest request) { if (request.ChannelName != ChannelName) { return(null); } try { Logger.LogInformation("Offer received..."); if (!_connectionInitialized) { InitConnection(); } Logger.LogInformation("Setting remote description..."); var result = _connection.setRemoteDescription(request.Offer.ToSessionDescription()); if (result != SetDescriptionResultEnum.OK) { throw new Exception("Error setting remote description."); } if (request.Offer.InternalType == RTCSdpType.offer) { Logger.LogInformation("Creating answer..."); var answer = _connection.createAnswer(null); Logger.LogInformation("Setting local description..."); _connection.setLocalDescription(answer).GetAwaiter().GetResult(); Logger.LogInformation("Sending answer response..."); return(new ResonanceActionResult <WebRTCOfferResponse>( new WebRTCOfferResponse() { ChannelName = ChannelName, Answer = WebRTCSessionDescription.FromSessionDescription(answer) })); } else { Logger.LogError($"Invalid offer type received '{request.Offer.InternalType}'."); } throw new Exception("Invalid offer request."); } catch (Exception ex) { FailConnection(ex); throw ex; } }
private async void OnConnectionStateChanged(RTCPeerConnectionState state) { if (state == RTCPeerConnectionState.failed) { if (!_connectionCompleted) { if (!_rolesReversed) { Logger.LogInformation("First connection attempt failed. Reversing roles..."); _rolesReversed = true; _canSendIceCandidates = false; DisposeConnection(); InitConnection(); if (Role == WebRTCAdapterRole.Accept) { try { Logger.LogInformation("Creating offer..."); RTCSessionDescriptionInit offer = _connection.createOffer(new RTCOfferOptions()); Logger.LogInformation("Setting local description..."); await _connection.setLocalDescription(offer); Logger.LogInformation("Sending offer request..."); var response = await _signalingTransporter.SendRequestAsync <WebRTCOfferRequest, WebRTCOfferResponse>(new WebRTCOfferRequest() { ChannelName = ChannelName, Offer = WebRTCSessionDescription.FromSessionDescription(offer) }, new ResonanceRequestConfig() { Timeout = TimeSpan.FromSeconds(10) }); if (response.Answer.InternalType == RTCSdpType.answer) { var result = _connection.setRemoteDescription(response.Answer.ToSessionDescription()); if (result != SetDescriptionResultEnum.OK) { throw new Exception("Error setting the remote description."); } } else { Logger.LogError($"Invalid answer type received '{response.Answer.InternalType}'."); } FlushIceCandidates(); } catch (Exception ex) { FailConnection(ex); } } } else { FailConnection(new Exception("Second connection attempt failed.")); } } else { OnFailed(new ResonanceWebRTCChannelClosedException("The WebRTC connection has failed.")); } } }
protected override Task OnConnect() { //SIPSorcery.LogFactory.Set(Resonance.ResonanceGlobalSettings.Default.LoggerFactory); _connectionInitialized = false; _rolesReversed = false; _connectionCompleted = false; _receivedSegments = new List <byte[]>(); _expectedSegments = 0; _expectedSegmentsCheckSum = null; _incomingQueue = new ProducerConsumerQueue <byte[]>(); _connectionCompletionSource = new TaskCompletionSource <object>(); Logger.LogInformation("Initializing adapter with role '{Role}'.", Role); Task.Factory.StartNew(async() => { try { Thread.Sleep(50); if (Role == WebRTCAdapterRole.Accept) { if (_offerRequest != null) { Logger.LogInformation("Adapter initialized by an offer request. Sending answer..."); var response = OnWebRTCOfferRequest(_offerRequest); _signalingTransporter.SendResponse(response.Response, _offerRequestToken); } else { Logger.LogInformation("Waiting for offer..."); } } else { InitConnection(); Logger.LogInformation("Creating offer..."); RTCSessionDescriptionInit offer = _connection.createOffer(new RTCOfferOptions()); Logger.LogInformation("Setting local description..."); await _connection.setLocalDescription(offer); Logger.LogInformation("Sending offer request..."); var response = await _signalingTransporter.SendRequestAsync <WebRTCOfferRequest, WebRTCOfferResponse>(new WebRTCOfferRequest() { ChannelName = ChannelName, Offer = WebRTCSessionDescription.FromSessionDescription(offer) }, new ResonanceRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); if (response.Answer.InternalType == RTCSdpType.answer) { Logger.LogInformation("Answer received, setting remove description..."); var result = _connection.setRemoteDescription(response.Answer.ToSessionDescription()); if (result != SetDescriptionResultEnum.OK) { throw new Exception("Error setting the remote description."); } } else { Logger.LogError($"Invalid answer type received '{response.Answer.InternalType}'."); } FlushIceCandidates(); } } catch (Exception ex) { FailConnection(ex); } }); return(_connectionCompletionSource.Task); }