public Task HandleAsync(IRemoteDevice remoteDevice, Guid peerConnectionId, Guid offerId, RTCSessionDescription answer) { Require.NotNull(answer.Sdp); Require.NotNull(answer.Type); Require.NotEmpty(offerId); Require.NotEmpty(peerConnectionId); // Get user and current IPeerConnection for this device var deviceData = remoteDevice.GetCustomData(); if (null == deviceData.User) { throw new UnauthorizedAccessException(); } // Get the PeerConnection that this answer is for var peerConnection = deviceData.PeerConnections.FirstOrDefault(p => p.Id == peerConnectionId); if (null == peerConnection) { throw new InvalidOperationException($"PeerConnection {peerConnectionId} does not exist for the device {remoteDevice}"); } _negotiationService.EnqueueRemoteAnswer(peerConnection, offerId, answer); return(Task.CompletedTask); }
public async Task DisconnectDeviceAsync(IRemoteDevice remoteDevice) { var deviceData = remoteDevice.GetCustomData(); if (deviceData.Room != null) { await deviceData.Room.SignallingThread.ExecuteAsync(delegate { // Close associated PeerConnections foreach (var peer in deviceData.PeerConnections) { using (peer) { peer.Close(); _logger.Debug($"{peer} closed due to device disconnect, device {remoteDevice}"); } } // Stop this device from sending data to ther devices deviceData.Room.VideoRouter.RemoveRemoteDevice(remoteDevice); }); } else { if (deviceData.PeerConnections.Any()) { throw new InvalidProgramException("Device NOT joined any room but somehow has PeerConnection"); } } // If this device associated with an user, // Move the association. if (deviceData.User != null) { await deviceData.User.Room.SignallingThread.ExecuteAsync(delegate { deviceData.User.Devices.Remove(remoteDevice); }); } // Clear any data associated with this device. // It's officially logged out remoteDevice.SetCustomData(new Models.RemoteDeviceData()); // Send status update so devices can update their UIs if (deviceData.Room != null) { await _syncMessenger.SendAsync(deviceData.Room); } }
public void Handle(IRemoteDevice remoteDevice, TransceiverMetadata metadata) { // Find the PeerConnection: // As the server uses only 1 PeerConnection // to send media, // the first PeerConnection is alwaus the one this ack is for. var peerConnection = remoteDevice.GetCustomData().PeerConnections.FirstOrDefault(); if (null == peerConnection) { throw new InvalidOperationException($"Device {remoteDevice} has no PeerConnection - ack what?"); } _negotiationService.EnqueueLocalTransceiverMetadataAck(peerConnection, metadata); }
public Task HandleAsync( IRemoteDevice remoteDevice, Guid?peerConnectionId, RTCSessionDescription offer, TransceiverMetadata[] transceivers) { Require.NotNull(offer.Sdp); Require.NotNull(offer.Type); // Ensure the user has logged in var deviceData = remoteDevice.GetCustomData(); if (null == deviceData.User) { throw new UnauthorizedAccessException(); } // Get or create new PeerConnection, depending on the client's requests IPeerConnection peerConnection = null; if (peerConnectionId != null) { peerConnection = deviceData.PeerConnections.First(p => p.Id == peerConnectionId.Value); } else { if (deviceData.PeerConnections.Count > 3) { throw new InvalidOperationException($"Max 3 PeerConnection allowed per device"); } peerConnection = CreatePeerConnection(remoteDevice, deviceData.User); } // Save deviceData.PeerConnections.Add(peerConnection); remoteDevice.SetCustomData(deviceData); // Let the negotiation service handle the rest // Notes - queue transceiver metadata first before queuing the remote sdp, // so at the time processing remote sdp (which has remote transceivers) // we know transceviers' metadata inhand. // Fail to do so will cause errors. _negotiationService.EnqueueRemoteTransceiverMetadata(peerConnection, transceivers); _negotiationService.EnqueueRemoteOffer(peerConnection, offer); return(Task.CompletedTask); }
public Task AddAsync(IRemoteDevice remoteDevice, Guid peerConnectionId, RTCIceCandidate iceCandidate) { var peerConnection = remoteDevice.GetCustomData().PeerConnections.FirstOrDefault(p => p.Id == peerConnectionId); if (null == peerConnection) { throw new InvalidOperationException( $"Could not find PeerConnection with Id {peerConnectionId} in {remoteDevice}" ); } if (null == peerConnection.Room) { throw new UnauthorizedAccessException( $"Device must join a room first before sending ICE candidates"); } _negotiationService.EnqueueRemoteIceCandidate(peerConnection, iceCandidate); return(Task.CompletedTask); }