private void _peerConnection_OnDataChannel(IRTCDataChannelEvent e) { var asd = RTCDataChannelEvent.Cast(e); Debug.WriteLine("Data Channel Girdi"); IRTCDataChannel channel = e.Channel; Debug.WriteLine(" Data Channel Eklendi " + channel.BinaryType); _rTCDataChannel = (RTCDataChannel)channel; _rTCDataChannel.OnMessage += _rTCDataChannel_OnMessage; }
public DataProducer(string id, IRTCDataChannel dataChannel, SctpStreamParameters sctpStreamParameters, Dictionary <string, object> appData) { Id = id; _dataChannel = dataChannel; SctpStreamParameters = sctpStreamParameters; AppData = appData; Closed = false; HandleDataChannel(); }
async Task CreateOrDeletePeerConnectionAsync(Guid peerId, string peerName, bool isInitiator, bool isDelete = false) { try { PeerContext peerContext = null; IRTCPeerConnection peerConnection = null; IMediaStream mediaStream = null; IRTCDataChannel dataChannel = null; if (isDelete) { peerContext = _connectionContext.PeerContexts.Single(context => context.Id.Equals(peerId)); peerConnection = peerContext.PeerConnection; peerConnection.OnConnectionStateChanged -= OnConnectionStateChanged; peerConnection.OnDataChannel -= OnDataChannel; peerConnection.OnIceCandidate -= OnIceCandidate; peerConnection.OnIceConnectionStateChange -= OnIceConnectionStateChange; peerConnection.OnIceGatheringStateChange -= OnIceGatheringStateChange; peerConnection.OnNegotiationNeeded -= OnNegotiationNeeded; peerConnection.OnSignallingStateChange -= OnSignallingStateChange; peerConnection.OnTrack -= OnTrack; // Remove local tracks and close. var senders = peerConnection.GetSenders(); foreach (var sender in senders) { peerConnection.RemoveTrack(sender); } peerConnection.Close(); _connectionContext.PeerContexts.Remove(peerContext); } else { mediaStream = _webRtc.Window(_jsRuntime).MediaStream(); RTCIceServer[] iceServers = _connectionContext.IceServers; if (iceServers is null) { var result = await _signalingServerApi.GetIceServersAsync(); if (!result.IsOk) { throw new Exception($"{result.ErrorMessage}"); } iceServers = result.Value; _connectionContext.IceServers = iceServers; } var configuration = new RTCConfiguration { IceServers = iceServers, //PeerIdentity = peerName }; _logger.LogInformation($"################ LIST OF ICE SERVERS ################"); foreach (var iceServer in configuration.IceServers) { foreach (var url in iceServer.Urls) { _logger.LogInformation($"\t - {url}"); } } _logger.LogInformation($"#####################################################"); peerConnection = _webRtc.Window(_jsRuntime).RTCPeerConnection(configuration); peerContext = new PeerContext { Id = peerId, Name = peerName, PeerConnection = peerConnection, IsInitiator = isInitiator, }; _connectionContext.PeerContexts.Add(peerContext); peerConnection.OnConnectionStateChanged += OnConnectionStateChanged; peerConnection.OnDataChannel += OnDataChannel; peerConnection.OnIceCandidate += OnIceCandidate; peerConnection.OnIceConnectionStateChange += OnIceConnectionStateChange; peerConnection.OnIceGatheringStateChange += OnIceGatheringStateChange; peerConnection.OnNegotiationNeeded += OnNegotiationNeeded; peerConnection.OnSignallingStateChange += OnSignallingStateChange; peerConnection.OnTrack += OnTrack; if (_connectionContext.UserContext.DataChannelName is not null && isInitiator) { dataChannel = peerConnection.CreateDataChannel( _connectionContext.UserContext.DataChannelName, new RTCDataChannelInit { Negotiated = false, }); } if (_connectionContext.UserContext.LocalStream is not null) { var videoTrack = _connectionContext.UserContext.LocalStream.GetVideoTracks().FirstOrDefault(); var audioTrack = _connectionContext.UserContext.LocalStream.GetAudioTracks().FirstOrDefault(); if (videoTrack is not null) { peerConnection.AddTrack(videoTrack, _connectionContext.UserContext.LocalStream); } if (audioTrack is not null) { peerConnection.AddTrack(audioTrack, _connectionContext.UserContext.LocalStream); } } } void OnConnectionStateChanged(object s, EventArgs e) { _logger.LogInformation( $"######## OnConnectionStateChanged - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"connectionState:{peerConnection.ConnectionState}"); if (peerConnection.ConnectionState == RTCPeerConnectionState.Connected) { _connectionContext.Observer.OnNext(new PeerResponse { Type = PeerResponseType.PeerJoined, Id = peerId, Name = peerName, MediaStream = mediaStream, DataChannel = isInitiator ? dataChannel : null }); } //// WILL BE HANDLED BY PEER LEFT //else if (peerConnection.ConnectionState == RTCPeerConnectionState.Disconnected) //ConnectionResponseSubject.OnCompleted(); } void OnDataChannel(object s, IRTCDataChannelEvent e) { _logger.LogInformation( $"######## OnDataChannel - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"state:{e.Channel.ReadyState}"); dataChannel?.Close(); dataChannel?.Dispose(); dataChannel = e.Channel; _connectionContext.Observer.OnNext(new PeerResponse { Type = PeerResponseType.PeerJoined, Name = peerName, MediaStream = null, DataChannel = dataChannel }); } async void OnIceCandidate(object s, IRTCPeerConnectionIceEvent e) { //_logger.LogInformation( // $"######## OnIceCandidate - room:{roomName} " + // $"user:{connectionContext.ConnectionRequestParameters.ConnectionParameters.UserName} " + // $"peerUser:{peerName}"); // 'null' is valid and indicates end of ICE gathering process. if (e.Candidate is not null) { var iceCandidate = new RTCIceCandidateInit { Candidate = e.Candidate.Candidate, SdpMid = e.Candidate.SdpMid, SdpMLineIndex = e.Candidate.SdpMLineIndex, //UsernameFragment = ??? }; var ice = JsonSerializer.Serialize(iceCandidate, JsonHelper.WebRtcJsonSerializerOptions); _logger.LogInformation( $"--------> Sending ICE Candidate - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"ice:{ice}"); var result = await _signalingServerApi.IceAsync(peerId, ice); if (!result.IsOk) { throw new Exception($"{result.ErrorMessage}"); } } } void OnIceConnectionStateChange(object s, EventArgs e) { _logger.LogInformation( $"######## OnIceConnectionStateChange - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"iceConnectionState:{peerConnection.IceConnectionState}"); } void OnIceGatheringStateChange(object s, EventArgs e) { _logger.LogInformation( $"######## OnIceGatheringStateChange - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"iceGatheringState: {peerConnection.IceGatheringState}"); } void OnNegotiationNeeded(object s, EventArgs e) { _logger.LogInformation( $"######## OnNegotiationNeeded - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName}"); // TODO: WHAT IF Not initiator adds track (which trigggers this event)??? } void OnSignallingStateChange(object s, EventArgs e) { _logger.LogInformation( $"######## OnSignallingStateChange - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName}, " + $"signallingState:{ peerConnection.SignalingState }"); //RoomEventSubject.OnNext(new RoomEvent //{ // Code = RoomEventCode.PeerJoined, // RoomName = roomName, // PeerUserName = peerName, // MediaStream = mediaStream //}); } void OnTrack(object s, IRTCTrackEvent e) { _logger.LogInformation( $"######## OnTrack - room:{_connectionContext.UserContext.Room} " + $"user:{_connectionContext.UserContext.Name} " + $"peerUser:{peerName} " + $"trackType:{e.Track.Kind}"); mediaStream.AddTrack(e.Track); } } catch (Exception ex) { _connectionContext?.Observer.OnNext(new PeerResponse { Type = PeerResponseType.PeerError, Id = peerId, Name = peerName, ErrorMessage = ex.Message }); } }