示例#1
0
        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);
            }
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }