/// <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(); }
/// <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); }
/// <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); }