Пример #1
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits transportclose</para>
        /// <para>@emits @close</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="dataProducerInternalData"></param>
        /// <param name="sctpStreamParameters"></param>
        /// <param name="label"></param>
        /// <param name="protocol"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        public DataProducer(ILoggerFactory loggerFactory,
                            DataProducerInternalData dataProducerInternalData,
                            SctpStreamParameters sctpStreamParameters,
                            string label,
                            string protocol,
                            Channel channel,
                            PayloadChannel payloadChannel,
                            Dictionary <string, object>?appData)
        {
            _logger = loggerFactory.CreateLogger <DataProducer>();

            // Internal
            Internal = dataProducerInternalData;

            // Data
            SctpStreamParameters = sctpStreamParameters;
            Label    = label;
            Protocol = protocol;

            _channel        = channel;
            _payloadChannel = payloadChannel;
            AppData         = appData;

            HandleWorkerNotifications();
        }
Пример #2
0
        /// <summary>
        /// Create a DataProducer.
        /// </summary>
        /// <returns></returns>
        public async Task <DataProducer> ProduceDataAsync(DataProducerOptions dataProducerOptions)
        {
            _logger.LogDebug("ProduceDataAsync()");

            if (!dataProducerOptions.Id.IsNullOrWhiteSpace() && DataProducers.ContainsKey(dataProducerOptions.Id !))
            {
                throw new Exception($"a DataProducer with same id {dataProducerOptions.Id} already exists");
            }

            if (dataProducerOptions.Label.IsNullOrWhiteSpace())
            {
                dataProducerOptions.Label = string.Empty;
            }
            if (dataProducerOptions.Protocol.IsNullOrWhiteSpace())
            {
                dataProducerOptions.Protocol = string.Empty;
            }

            // This may throw.
            ORTC.ValidateSctpStreamParameters(dataProducerOptions.SctpStreamParameters);

            var @internal = new DataProducerInternalData
                            (
                Internal.RouterId,
                Internal.TransportId,
                !dataProducerOptions.Id.IsNullOrWhiteSpace() ? dataProducerOptions.Id : Guid.NewGuid().ToString()
                            );

            var reqData = new
            {
                dataProducerOptions.SctpStreamParameters,
                Label    = dataProducerOptions.Label !,
                Protocol = dataProducerOptions.Protocol !
            };

            var status = await Channel.RequestAsync(MethodId.TRANSPORT_PRODUCE_DATA, @internal, reqData);

            var responseData = JsonConvert.DeserializeObject <TransportDataProduceResponseData>(status);
            var dataProducer = new DataProducer(_loggerFactory,
                                                @internal,
                                                responseData.SctpStreamParameters,
                                                responseData.Label,
                                                responseData.Protocol,
                                                Channel,
                                                AppData);

            DataProducers[dataProducer.Internal.DataProducerId] = dataProducer;

            dataProducer.On("@close", _ =>
            {
                DataProducers.Remove(dataProducer.Internal.DataProducerId);
                Emit("@dataproducerclose", dataProducer);
            });

            Emit("@newdataproducer", dataProducer);

            // Emit observer event.
            Observer.Emit("newdataproducer", dataProducer);

            return(dataProducer);
        }
Пример #3
0
        /// <summary>
        /// Create a DataProducer.
        /// </summary>
        /// <returns></returns>
        public async Task <DataProducer> ProduceDataAsync(DataProducerOptions dataProducerOptions)
        {
            _logger.LogDebug($"ProduceDataAsync() | Transport:{TransportId}");

            if (!dataProducerOptions.Id.IsNullOrWhiteSpace() && DataProducers.ContainsKey(dataProducerOptions.Id !))
            {
                throw new Exception($"A DataProducer with same id {dataProducerOptions.Id} already exists");
            }

            if (dataProducerOptions.Label.IsNullOrWhiteSpace())
            {
                dataProducerOptions.Label = string.Empty;
            }
            if (dataProducerOptions.Protocol.IsNullOrWhiteSpace())
            {
                dataProducerOptions.Protocol = string.Empty;
            }

            DataProducerType type;

            // If this is not a DirectTransport, sctpStreamParameters are required.
            // TODO: (alby)反模式
            if (GetType() != typeof(DirectTransport))
            {
                type = DataProducerType.Sctp;

                // This may throw.
                ORTC.ValidateSctpStreamParameters(dataProducerOptions.SctpStreamParameters !);
            }
            // If this is a DirectTransport, sctpStreamParameters must not be given.
            else
            {
                type = DataProducerType.Direct;

                if (dataProducerOptions.SctpStreamParameters != null)
                {
                    _logger.LogWarning($"ProduceDataAsync() | Transport:{TransportId} sctpStreamParameters are ignored when producing data on a DirectTransport");
                }
            }

            var @internal = new DataProducerInternalData
                            (
                Internal.RouterId,
                Internal.TransportId,
                dataProducerOptions.Id.NullOrWhiteSpaceReplace(Guid.NewGuid().ToString())
                            );

            var reqData = new
            {
                Type = type.GetEnumStringValue(),
                dataProducerOptions.SctpStreamParameters,
                Label    = dataProducerOptions.Label !,
                Protocol = dataProducerOptions.Protocol !
            };

            var status = await Channel.RequestAsync(MethodId.TRANSPORT_PRODUCE_DATA, @internal, reqData);

            var responseData = JsonConvert.DeserializeObject <TransportDataProduceResponseData>(status !);
            var dataProducer = new DataProducer(_loggerFactory,
                                                @internal,
                                                responseData.SctpStreamParameters,
                                                responseData.Label !,
                                                responseData.Protocol !,
                                                Channel,
                                                PayloadChannel,
                                                AppData);

            dataProducer.On("@close", async _ =>
            {
                await DataProducersLock.WaitAsync();
                try
                {
                    DataProducers.Remove(dataProducer.DataProducerId);
                }
                finally
                {
                    DataProducersLock.Set();
                }
                Emit("@dataproducerclose", dataProducer);
            });

            await DataProducersLock.WaitAsync();

            try
            {
                DataProducers[dataProducer.DataProducerId] = dataProducer;
            }
            finally
            {
                DataProducersLock.Set();
            }

            Emit("@newdataproducer", dataProducer);

            // Emit observer event.
            Observer.Emit("newdataproducer", dataProducer);

            return(dataProducer);
        }